Source Code
Overview
ETH Balance
ETH Value
$0.00Latest 22 from a total of 22 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Pause | 57748 | 914 days ago | IN | 0 ETH | 0.00005764 | ||||
| Pause | 57748 | 914 days ago | IN | 0 ETH | 0.00059697 | ||||
| Execute Round | 57748 | 914 days ago | IN | 0 ETH | 0.00034431 | ||||
| Execute Round | 57748 | 914 days ago | IN | 0 ETH | 0.00034431 | ||||
| Start Prediction... | 45081 | 916 days ago | IN | 0 ETH | 0.0004179 | ||||
| Create Predictio... | 44966 | 916 days ago | IN | 0 ETH | 0.00178276 | ||||
| Un Pause | 44964 | 916 days ago | IN | 0 ETH | 0.00015068 | ||||
| Set Min Predict ... | 44961 | 916 days ago | IN | 0 ETH | 0.00012533 | ||||
| Pause | 44956 | 916 days ago | IN | 0 ETH | 0.00089522 | ||||
| Execute Round | 43155 | 916 days ago | IN | 0 ETH | 0.00034427 | ||||
| Execute Round | 43155 | 916 days ago | IN | 0 ETH | 0.00034427 | ||||
| Execute Round | 42927 | 917 days ago | IN | 0 ETH | 0.00045326 | ||||
| Execute Round | 42837 | 917 days ago | IN | 0 ETH | 0.00045326 | ||||
| Start Prediction... | 42763 | 917 days ago | IN | 0 ETH | 0.00020214 | ||||
| Create Predictio... | 42659 | 917 days ago | IN | 0 ETH | 0.00073413 | ||||
| Un Pause | 42647 | 917 days ago | IN | 0 ETH | 0.00006471 | ||||
| Pause | 42645 | 917 days ago | IN | 0 ETH | 0.00044944 | ||||
| Create Predictio... | 8894 | 921 days ago | IN | 0 ETH | 0.00095206 | ||||
| Create Predictio... | 8061 | 921 days ago | IN | 0 ETH | 0.00055018 | ||||
| Create Predictio... | 8061 | 921 days ago | IN | 0 ETH | 0.00056704 | ||||
| Set Operator | 2226 | 922 days ago | IN | 0 ETH | 0.00007885 | ||||
| Set Bhavish SDK | 2225 | 922 days ago | IN | 0 ETH | 0.00007511 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH | ||||
| 57748 | 914 days ago | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
NativeCP
Compiler Version
v0.8.13+commit.abaa5c0e
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BSD-4-Clause
pragma solidity ^0.8.13;
import { AbstractCP, IBhavishAdministrator, IPriceManager, BhavishPredictionStorage } from "./AbstractCP.sol";
import { AbstractNative, IBhavishSwap } from "../AbstractNative.sol";
/**
* @title BhavishPrediction
*/
contract NativeCP is AbstractCP, AbstractNative {
constructor(
uint256 _minPredictAmount,
uint256 _treasuryFee,
IBhavishAdministrator _bhavishAdmin,
IPriceManager _bhavishPriceManager,
BhavishPredictionStorage _bhavishPredictionStorage,
IBhavishSwap _bhavishSwap,
uint256 _roundTime,
bytes32 _underlying,
bytes32 _strike
)
AbstractCP(
_minPredictAmount,
_treasuryFee,
_bhavishAdmin,
_bhavishPriceManager,
_bhavishPredictionStorage,
_roundTime,
_underlying,
_strike
)
AbstractNative(_bhavishSwap)
{}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)
pragma solidity ^0.8.0;
import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.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:
*
* ```
* 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}:
*
* ```
* 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.
*/
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(uint160(account), 20),
" 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());
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)
pragma solidity ^0.8.0;
/**
* @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;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
constructor() {
_paused = false;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "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");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(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) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(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) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason 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 {
// 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);
}
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @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;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165.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;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @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);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)
pragma solidity ^0.8.0;
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _HEX_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) {
// Inspired by OraclizeAPI's implementation - MIT licence
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
/**
* @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] = _HEX_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);
}
}// SPDX-License-Identifier: BSD-4-Clause
pragma solidity ^0.8.13;
import { AbstractPrediction, Address } from "./AbstractPrediction.sol";
import { IBhavishPredictionNative } from "../../Interface/IBhavishPredictionNative.sol";
import { IBhavishSwap } from "../../Interface/IBhavishSwap.sol";
abstract contract AbstractNative is AbstractPrediction, IBhavishPredictionNative {
// Implementation for IBhavishPredictionNative methods -------
using Address for address;
IBhavishSwap public bhavishSwap;
constructor(IBhavishSwap _bhavishSwap) {
require(address(_bhavishSwap).isContract(), "Swapper is not a contract");
bhavishSwap = _bhavishSwap;
}
function predictUp(uint256 _predictRoundId, address _userAddress) external payable whenNotPaused nonReentrant {
_predictUp(_predictRoundId, _userAddress, msg.value);
}
function predictDown(uint256 _predictRoundId, address _userAddress) external payable whenNotPaused nonReentrant {
_predictDown(_predictRoundId, _userAddress, msg.value);
}
function claim(
uint256[] calldata _roundIds,
address _userAddress,
SwapParams memory _swapParams
) external nonReentrant returns (uint256 reward) {
(reward, ) = _claim(_roundIds, _userAddress);
if (_swapParams.convert && reward > 0) {
IBhavishSwap.SwapStruct memory swapStruct = IBhavishSwap.SwapStruct({
deadline: block.timestamp + (roundTime * 2),
fromAsset: bytes32("MATIC"),
toAsset: _swapParams.toAsset,
amountIn: 0
});
bhavishSwap.swapExactETHForTokens{ value: reward }(swapStruct, _userAddress, _swapParams.slippage);
} else if (reward > 0) _amountTransfer(_userAddress, reward);
}
function _setAmountDispersed(
uint256 _roundId,
address _user,
uint256 _reward,
uint256 _betAmount
) internal override {
bhavishPredictionStorage.setBetAmountDispersed(_roundId, _user, _reward);
}
// Implementation for Abstract Crupto Prediction virtual methods -------
function _updateCalculateRewards(uint256 _burn, uint256 _mint) internal override {}
function _getRoundRewardAmount(Round memory _round) internal pure override returns (uint256 rewardAmount) {
rewardAmount = _round.totalAmount;
}
function _calcRewardsForUser(Round memory _round, BetInfo memory _betInfo)
internal
view
override
returns (uint256 addedReward, uint256 winningBetAmount)
{
//check's for a tie
if (_round.endPrice == _round.startPrice) {
uint256 betAmount = _betInfo.upPredictAmount + _betInfo.downPredictAmount;
if (_refundable(_round)) addedReward = betAmount - ((betAmount * treasuryFee) / 10**decimals);
} else if (_round.endPrice > _round.startPrice) {
winningBetAmount = _betInfo.upPredictAmount;
addedReward = (_betInfo.upPredictAmount * _round.rewardAmount) / _round.rewardBaseCalAmount;
} else if (_round.endPrice < _round.startPrice) {
winningBetAmount = _betInfo.downPredictAmount;
addedReward = (_betInfo.downPredictAmount * _round.rewardAmount) / _round.rewardBaseCalAmount;
}
}
function _amountTransfer(address _user, uint256 _amount) internal override {
(bool success, ) = _user.call{ value: _amount }("");
require(success, "TransferHelper: TRANSFER_FAILED");
}
function _treasuryFeeTransfer(address _user, uint256 _amount) internal override {
_amountTransfer(_user, _amount);
}
function updateBhavishSwap(IBhavishSwap _swap) external onlyAdmin(msg.sender) {
bhavishSwap = _swap;
}
}// SPDX-License-Identifier: BSD-4-Clause
pragma solidity ^0.8.13;
import { Pausable } from "@openzeppelin/contracts/security/Pausable.sol";
import { AccessControl } from "@openzeppelin/contracts/access/AccessControl.sol";
import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import { IBhavishAdministrator } from "../../Interface/IBhavishAdministrator.sol";
import { IPriceManager } from "../../Interface/IPriceManager.sol";
import { IBhavishPrediction } from "../../Interface/IBhavishPrediction.sol";
import { BhavishPredictionStorage, Address } from "./BhavishPredictionStorage.sol";
/**
* @title BhavishPrediction
*/
abstract contract AbstractPrediction is IBhavishPrediction, AccessControl, Pausable, ReentrancyGuard {
using Address for address;
uint256 public currentRoundId;
uint256 public roundTime; //10 mintues of round
uint256 public roundzeroStartTimestamp;
PredictionMarketStatus public marketStatus;
uint256 public treasuryFee;
uint256 public vaultDiscountPerc;
uint256 public constant MAX_TREASURY_FEE = 100; // 10%
uint256 public minPredictAmount; // minimum prediction amount (denominated in wei)
uint256 public treasuryAmount; // funds in treasury collected from fee
uint256 public decimals = 3;
address public bhavishSDK;
// State variables for storing the underlying and strike asset names -- Need to revisit this logic in later versions
AssetPair public assetPair;
IBhavishAdministrator public bhavishAdmin;
IPriceManager public bhavishPriceManager;
BhavishPredictionStorage public bhavishPredictionStorage;
mapping(address => bool) public isVault;
bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");
bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE");
event PausedMarket(uint256 currentRoundId);
event UnPausedMarket(uint256 currentRoundId);
event CreateRound(uint256 indexed roundId);
event StartRound(uint256 indexed roundId);
event EndRound(uint256 indexed roundId);
event CancelRound(uint256 indexed roundId);
event NewBhvaishSDK(address indexed _sdk);
event PredictUp(address indexed sender, uint256 indexed roundId, uint256 amount);
event PredictDown(address indexed sender, uint256 indexed roundId, uint256 amount);
event RewardsCalculated(
uint256 indexed roundId,
uint256 rewardBaseCalAmount,
uint256 rewardAmount,
uint256 treasuryAmount
);
event Refund(uint256 indexed roundId, address indexed recipient, uint256 refundDispersed, uint256 timestamp);
event NewMinPredictAmount(uint256 minPredictAmount);
event NewTreasuryFee(uint256 treasuryFee);
event NewVaultDiscountPercentage(uint256 vaultDiscountPerc);
event NewOperator(address indexed operator);
event NewAdmin(address indexed admin);
event TransferToAdmin(address indexed bhavishAdmin, uint256 amount);
event Claim(address indexed sender, uint256 indexed roundId, uint256 amount);
/**
* @notice Constructor
* @param _minPredictAmount minimum bet amounts (in wei)
* @param _treasuryFee treasury fee (1000 = 10%)
* @param _bhavishAdmin Bhavish Administrator
* @param _bhavishPriceManager Price Manager
* @param _underlying Name of the underlying asset
* @param _strike Name of the strike asset
*/
constructor(
uint256 _minPredictAmount,
uint256 _treasuryFee,
IBhavishAdministrator _bhavishAdmin,
IPriceManager _bhavishPriceManager,
BhavishPredictionStorage _bhavishPredictionStorage,
uint256 _roundTime,
bytes32 _underlying,
bytes32 _strike
) {
require(_minPredictAmount > 0, "Invalid Min Predict amount");
require(_treasuryFee > 0 && _treasuryFee < MAX_TREASURY_FEE, "Treasury fee is too high");
require(0 < _roundTime && _roundTime <= 86400, "Round Time should be between 1 sec to 3600 sec");
minPredictAmount = _minPredictAmount;
treasuryFee = _treasuryFee;
vaultDiscountPerc = 100;
bhavishAdmin = _bhavishAdmin;
bhavishPriceManager = _bhavishPriceManager;
bhavishPredictionStorage = _bhavishPredictionStorage;
AssetPair memory pair = AssetPair(_underlying, _strike);
assetPair = pair;
roundTime = _roundTime;
currentRoundId = bhavishPredictionStorage.latestRoundId();
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
}
// Implement virtual methods ---------
function _getRoundRewardAmount(Round memory _round) internal pure virtual returns (uint256 rewardAmount);
function _updateCalculateRewards(uint256 _burn, uint256 _mint) internal virtual;
function _calcRewardsForUser(Round memory _round, BetInfo memory _betInfo)
internal
view
virtual
returns (uint256 addedReward, uint256 betAmount);
function _amountTransfer(address _user, uint256 _amount) internal virtual;
function _treasuryFeeTransfer(address _user, uint256 _amount) internal virtual;
function _setAmountDispersed(
uint256 _roundId,
address _user,
uint256 _reward,
uint256 _amount
) internal virtual;
// Modifiers go here --------
modifier onlyAdmin(address _address) {
require(hasRole(DEFAULT_ADMIN_ROLE, _address), "Address not an admin");
_;
}
modifier onlyOperator(address _address) {
require(hasRole(OPERATOR_ROLE, _address), "Address not an operator");
_;
}
modifier validateUser(address _userAddress) {
if (msg.sender != _userAddress) {
require(msg.sender == bhavishSDK, "Invalid Caller");
}
_;
}
// Roles granting goes here --------
/**
* @notice Set operator
* @dev callable by Admin of the contract
* @param _operator new operator address
*/
function setOperator(address _operator) external onlyAdmin(msg.sender) {
require(_operator != address(0), "Cannot be zero address");
grantRole(OPERATOR_ROLE, _operator);
emit NewOperator(_operator);
}
/**
* @notice Set the bhavish administrator
* @param _bhavishAdministrator Address of the bhavish admin contract
*/
function setBhavishAdministrator(IBhavishAdministrator _bhavishAdministrator) external onlyAdmin(msg.sender) {
require(address(_bhavishAdministrator).isContract(), "Not Bhavish Administrator");
bhavishAdmin = _bhavishAdministrator;
}
function addVault(address _vault) external onlyAdmin(msg.sender) {
require(_vault.isContract(), "invalid vault");
isVault[_vault] = true;
}
/**
* @notice Remove operator
* @dev callable by Admin of the contract
* @param _address current operator
*/
function removeOperator(address _address) external onlyAdmin(msg.sender) {
revokeRole(OPERATOR_ROLE, _address);
}
// This is need for this contract to accept native currency
/**
* @notice Add funds
*/
receive() external payable {}
// Pause/Unpause the contract logic goes here --------
/**
* @notice Pause the contract
* @dev Callable by admin
*/
function pause() external whenNotPaused onlyOperator(msg.sender) {
_pause();
for (
uint256 tempRoundId = currentRoundId;
tempRoundId <= bhavishPredictionStorage.latestRoundId();
tempRoundId++
) {
Round memory round = bhavishPredictionStorage.getPredictionRound(tempRoundId);
if (round.roundState != RoundState.CANCELLED) {
_cancelRound(tempRoundId);
}
}
emit PausedMarket(currentRoundId);
}
/**
* @notice Unpuase the contract
* @dev Callable by admin
*/
function unPause() external whenPaused onlyOperator(msg.sender) {
marketStatus.createPredictionMarketOnce = false;
marketStatus.startPredictionMarketOnce = false;
currentRoundId = bhavishPredictionStorage.latestRoundId();
_unpause();
emit UnPausedMarket(currentRoundId);
}
// Set the min reqs for the contract goes here ---------
/**
* @notice Set minPredictAmount
* @dev Callable by admin
* @param _minPredictAmount minimum Predict amount to be set
*/
function setMinPredictAmount(uint256 _minPredictAmount) external whenPaused onlyAdmin(msg.sender) {
require(_minPredictAmount > 0, "Must be superior to 0");
minPredictAmount = _minPredictAmount;
emit NewMinPredictAmount(_minPredictAmount);
}
/**
* @notice Set Treasury Fee
* @dev Callable by admin
* @param _treasuryFee new treasury fee
*/
function setTreasuryFee(uint256 _treasuryFee) external whenPaused onlyAdmin(msg.sender) {
require(_treasuryFee > 0 && _treasuryFee < MAX_TREASURY_FEE, "Treasury fee is too high");
treasuryFee = _treasuryFee;
emit NewTreasuryFee(_treasuryFee);
}
/**
* @notice Set Treasury Fee
* @dev Callable by admin
* @param _discountPerc new vault discount percentage
*/
function setVaultDiscountPerc(uint256 _discountPerc) external whenPaused onlyAdmin(msg.sender) {
require(_discountPerc <= 100, "Vault discount perc is too high");
vaultDiscountPerc = _discountPerc;
emit NewVaultDiscountPercentage(_discountPerc);
}
/**
* @notice Set Bhavish SDK
* @dev Callable by admin
* @param _sdk new _sdk
*/
function setBhavishSDK(address _sdk) external onlyAdmin(msg.sender) {
require(_sdk.isContract(), "invalid address");
bhavishSDK = _sdk;
emit NewBhvaishSDK(_sdk);
}
/**
* @notice Set the round time
* @dev Callable by operator
* @param _roundTime round time
*/
function setRoundTime(uint256 _roundTime) external whenPaused onlyOperator(msg.sender) {
require(0 < _roundTime && _roundTime <= 86400, "Round Time should be between 1 sec to 3600 sec");
roundTime = _roundTime;
}
// Prediction logic goes here --------
/**
* @notice Create Round
* @param roundId round Id
* @param _startTimestamp Round start timestamp
*/
function _createRound(uint256 roundId, uint256 _startTimestamp) internal {
Round memory round = bhavishPredictionStorage.getPredictionRound(roundId);
require(round.roundId == 0, "Round already exists");
require(_startTimestamp - roundTime >= block.timestamp, "Round time is too short");
round.roundId = roundId;
round.roundStartTimestamp = _startTimestamp;
round.roundEndTimestamp = round.roundStartTimestamp + roundTime;
round.roundState = RoundState.CREATED;
bhavishPredictionStorage.createPredictionRound(round);
emit CreateRound(roundId);
}
/**
* @notice Start Round
* @param _predictRoundId round Id
* @param _price Price of the asset
*/
function _startRound(uint256 _predictRoundId, uint256 _price) internal {
Round memory round = bhavishPredictionStorage.getPredictionRound(_predictRoundId);
if (_price == 0) {
_cancelRound(_predictRoundId);
} else {
require(round.roundState == RoundState.CREATED, "Round should be created");
require(round.roundStartTimestamp <= block.timestamp, "Too early to start the round");
bhavishPredictionStorage.setRoundState(_predictRoundId, RoundState.STARTED, _price, true);
emit StartRound(_predictRoundId);
}
}
/**
* @notice Cancel the round
* @param _predictRoundId Round id of the round that needs to be cancelled
*/
function _cancelRound(uint256 _predictRoundId) internal {
Round memory round = bhavishPredictionStorage.getPredictionRound(_predictRoundId);
require(round.roundState != RoundState.CANCELLED, "Cannot cancel already cancelled round");
bhavishPredictionStorage.cancelRound(_predictRoundId);
emit CancelRound(_predictRoundId);
}
/**
* @notice End Round
* @param _predictRoundId round Id
* @param _price Price of the asset
*/
function _endRound(uint256 _predictRoundId, uint256 _price) internal {
Round memory round = bhavishPredictionStorage.getPredictionRound(_predictRoundId);
require(round.roundState == RoundState.STARTED, "Round is not started yet");
require(round.roundEndTimestamp <= block.timestamp, "Too early to end the round");
bhavishPredictionStorage.setRoundState(_predictRoundId, RoundState.ENDED, _price, false);
emit EndRound(_predictRoundId);
}
/**
* @notice Calculate Rewards for the round
* @param _predictRoundId round Id
*/
function _calculateRewards(uint256 _predictRoundId) internal {
Round memory round = bhavishPredictionStorage.getPredictionRound(_predictRoundId);
require(round.roundState == RoundState.ENDED, "Round is not ended");
uint256 rewardAmount = _getRoundRewardAmount(round);
uint256 treasuryAmt = (round.totalAmount * treasuryFee) / (10**decimals);
uint256 rewardBaseCalAmount;
// Bull wins
if (round.endPrice > round.startPrice) {
rewardBaseCalAmount = round.upPredictAmount;
// reward amount can be zero while treasury can be greater than reward for few cases
if (rewardAmount > 0 && rewardAmount > treasuryAmt) rewardAmount = rewardAmount - treasuryAmt;
// case when there are no bets on winning side. loosing side bets should be moved to treasury
if (rewardBaseCalAmount == 0) {
treasuryAmt = round.downPredictAmount;
rewardAmount = 0;
}
}
// Bear wins
else if (round.endPrice < round.startPrice) {
rewardBaseCalAmount = round.downPredictAmount;
if (rewardAmount > 0 && rewardAmount > treasuryAmt) rewardAmount = rewardAmount - treasuryAmt;
// case when there are no bets on winning side. loosing side bets should be moved to treasury
if (rewardBaseCalAmount == 0) {
treasuryAmt = round.upPredictAmount;
rewardAmount = 0;
}
}
// draw or tie
else {
rewardBaseCalAmount = 0;
rewardAmount = 0;
}
treasuryAmount += treasuryAmt;
bhavishPredictionStorage.setRewardAmountForRound(_predictRoundId, rewardAmount, rewardBaseCalAmount);
_updateCalculateRewards(rewardAmount + treasuryAmt, treasuryAmt);
emit RewardsCalculated(_predictRoundId, rewardBaseCalAmount, rewardAmount, treasuryAmt);
}
/**
* @notice Check whether the round is refundable
* @param _predictRound round details
*/
function _refundable(Round memory _predictRound) internal pure returns (bool) {
return
_predictRound.rewardBaseCalAmount == 0 &&
_predictRound.rewardAmount == 0 &&
_predictRound.startPrice == _predictRound.endPrice;
}
/**
* @notice Transfer the funds to bhavish admin contract_predictRound
* @param _amount Amount to be transfered
*/
function transferToAdmin(uint256 _amount) external payable nonReentrant onlyAdmin(msg.sender) {
require(_amount <= treasuryAmount, "Transfer amount is too large");
treasuryAmount -= _amount;
address bhavishAdminAddress = address(bhavishAdmin);
_treasuryFeeTransfer(bhavishAdminAddress, _amount);
emit TransferToAdmin(bhavishAdminAddress, _amount);
}
/**
* @notice Bet Bull position
* @param _predictRoundId Round Id
* @param _userAddress Address of the user
*/
function _predictUp(
uint256 _predictRoundId,
address _userAddress,
uint256 _amount
) internal validateUser(_userAddress) {
Round memory round = bhavishPredictionStorage.getPredictionRound(_predictRoundId);
require(round.roundState == RoundState.CREATED && round.roundId != 0, "Bet is too early/late");
require(block.timestamp <= round.roundStartTimestamp, "round already started");
require(_amount >= minPredictAmount, "Bet amount must be greater than minBetAmount");
// Update round data
bhavishPredictionStorage.setAmount(_predictRoundId, _amount, true);
BetInfo memory betInfo = bhavishPredictionStorage.getBetInfo(_predictRoundId, _userAddress);
// Update user data
if (betInfo.upPredictAmount == 0 && betInfo.downPredictAmount == 0) {
bhavishPredictionStorage.setLedgerInfo(_userAddress, _predictRoundId);
}
bhavishPredictionStorage.setBetInfo(_amount, _predictRoundId, _userAddress, true);
emit PredictUp(_userAddress, _predictRoundId, _amount);
}
/**
* @notice Bet Bear position
* @param _predictRoundId Round Id
* @param _userAddress Address of the user
*/
function _predictDown(
uint256 _predictRoundId,
address _userAddress,
uint256 _amount
) internal validateUser(_userAddress) {
Round memory round = bhavishPredictionStorage.getPredictionRound(_predictRoundId);
require(block.timestamp <= round.roundStartTimestamp, "round already started");
require(round.roundState == RoundState.CREATED && round.roundId != 0, "Bet is too early/late");
require(_amount >= minPredictAmount, "Bet amount must be greater than minBetAmount");
// Update round data
bhavishPredictionStorage.setAmount(_predictRoundId, _amount, false);
// Update user data
BetInfo memory betInfo = bhavishPredictionStorage.getBetInfo(_predictRoundId, _userAddress);
if (betInfo.upPredictAmount == 0 && betInfo.downPredictAmount == 0) {
bhavishPredictionStorage.setLedgerInfo(_userAddress, _predictRoundId);
}
bhavishPredictionStorage.setBetInfo(_amount, _predictRoundId, _userAddress, false);
emit PredictDown(_userAddress, _predictRoundId, _amount);
}
/**
* @notice Start Zero round
* @dev callable by Operator
*/
function startPredictionMarket() external override whenNotPaused onlyOperator(msg.sender) {
require(marketStatus.createPredictionMarketOnce, "Can only run after roundzeroCreateRound is triggered");
require(!marketStatus.startPredictionMarketOnce, "Can only run roundzeroStartRound once");
require(block.timestamp >= roundzeroStartTimestamp, "Round cannot be started early");
(uint256 price, ) = bhavishPriceManager.getPrice(
assetPair.underlying,
assetPair.strike,
roundzeroStartTimestamp
);
_startRound(currentRoundId, price);
marketStatus.startPredictionMarketOnce = true;
}
/**
* @notice Start Zero round
* @dev callable by Operator
*/
function startPredictionMarket(uint256 _price) external override whenNotPaused onlyOperator(msg.sender) {
require(marketStatus.createPredictionMarketOnce, "Can only run after roundzeroCreateRound is triggered");
require(!marketStatus.startPredictionMarketOnce, "Can only run roundzeroStartRound once");
require(block.timestamp >= roundzeroStartTimestamp, "Round cannot be started early");
_startRound(currentRoundId, _price);
marketStatus.startPredictionMarketOnce = true;
}
/**
* @notice Get the _claimable stats of specific round id and user account
* @param _round: round details
* @param _betInfo: bet info of a user
*/
function _claimable(Round memory _round, BetInfo memory _betInfo) public pure returns (bool) {
return
(_betInfo.upPredictAmount != 0 || _betInfo.downPredictAmount != 0) &&
_betInfo.amountDispersed == 0 &&
((_round.endPrice > _round.startPrice && _betInfo.upPredictAmount != 0) ||
(_round.endPrice < _round.startPrice && _betInfo.downPredictAmount != 0) ||
(_round.endPrice == _round.startPrice));
}
/**
* @notice claim reward
* @param roundIds: round Ids
*/
function _claim(uint256[] memory roundIds, address userAddress)
internal
validateUser(userAddress)
returns (uint256 reward, uint256 bet)
{
for (uint256 i = 0; i < roundIds.length; i++) {
Round memory round = bhavishPredictionStorage.getPredictionRound(roundIds[i]);
BetInfo memory betInfo = bhavishPredictionStorage.getBetInfo(roundIds[i], userAddress);
require(round.roundState == RoundState.ENDED, "Round not eligible for rewards");
require(round.totalAmount > 0, "No bets in the round");
if (round.startPrice == round.endPrice) require(_refundable(round), "Not eligible for refund");
if (_claimable(round, betInfo)) {
(uint256 addedReward, uint256 betAmount) = _calcRewardsForUser(round, betInfo);
if (isVault[userAddress]) addedReward = _updateVaultReward(addedReward);
_setAmountDispersed(round.roundId, userAddress, addedReward, betAmount);
reward += addedReward;
bet += betAmount;
emit Claim(userAddress, roundIds[i], addedReward);
}
}
}
function _updateVaultReward(uint256 oldReward) private returns (uint256 reward) {
// if Vault winning 20 Matic and considering 3% protocol fee for ease of calc
// oldReward will be 19.4
reward = oldReward;
// 19.4 / (1 - protocol fee %) provides original winning amount before treasury fee
// treasury fee can't be more than 10% as defined above
uint256 oWin = (oldReward * 1e3) / (1e3 - treasuryFee);
// tFeeCollected = oWin - reward;
// NOTE: vaultDiscountPerc can't be greater than equal to 100
// new fee will always be less or equal to old fee. We need to deduct this amount from treasuryFee
// newDiscountedFee = (oWin * treasuryFee * (100 - vaultDiscountPerc)) / 1e5;
// eg: 20 - ( 20 * 30 * (100 - 33) / 1e5 )
reward = oWin - (oWin * treasuryFee * (100 - vaultDiscountPerc)) / 1e5;
// old reward will always be higher or equal to new reward
// subtract this new amount from original amount and provide that as addedReward
if (treasuryAmount > reward - oldReward) treasuryAmount -= reward - oldReward;
else reward = oldReward; // can't reduce reward as treasury amount is zero
}
function getAverageBetAmount(uint256[] calldata roundIds, address userAddress)
external
view
override
returns (uint256 betAmount)
{
for (uint256 i = 0; i < roundIds.length; i++) {
BetInfo memory betInfo = bhavishPredictionStorage.getBetInfo(roundIds[i], userAddress);
betAmount += betInfo.downPredictAmount + betInfo.upPredictAmount;
}
if (roundIds.length > 0) betAmount /= roundIds.length;
}
/**
* @notice getRewards reward
* @param roundIds: round Ids
*/
function getRewards(uint256[] memory roundIds, address userAddress) public view returns (uint256) {
uint256 totalReward = 0;
for (uint256 i = 0; i < roundIds.length; i++) {
Round memory round = bhavishPredictionStorage.getPredictionRound(roundIds[i]);
BetInfo memory betInfo = bhavishPredictionStorage.getBetInfo(roundIds[i], userAddress);
if (!_claimable(round, betInfo)) {
continue;
}
(uint256 reward, ) = _calcRewardsForUser(round, betInfo);
totalReward += reward;
}
return totalReward;
}
/**
* @notice Refund to users if a round is cancelled
* @param _predictRoundId Round id of the cancelled round
*/
function refundUsers(uint256 _predictRoundId, address userAddress) public override nonReentrant {
Round memory round = bhavishPredictionStorage.getPredictionRound(_predictRoundId);
require(round.roundState == RoundState.CANCELLED, "User not eligible for refund");
BetInfo memory betInfo = bhavishPredictionStorage.getBetInfo(_predictRoundId, userAddress);
require(betInfo.amountDispersed == 0, "Refund already claimed");
uint256 amtInvested = betInfo.upPredictAmount + betInfo.downPredictAmount;
if (amtInvested > 0) {
bhavishPredictionStorage.setBetAmountDispersed(_predictRoundId, userAddress, amtInvested);
_amountTransfer(userAddress, amtInvested);
emit Refund(_predictRoundId, userAddress, amtInvested, block.timestamp);
}
}
function getCurrentRoundDetails() external view returns (IBhavishPrediction.Round memory round) {
round = bhavishPredictionStorage.getPredictionRound(currentRoundId);
}
/**
* @notice return user history
* @param _user address of user
* @param _index index of the round array from which data has to be returned
* @param _limit max limit to be returned per call
* @return _history history of user as array
* @return _nextIndex next index for to retrieve data from
*/
function getUserHistory(
address _user,
uint256 _index,
uint256 _limit
) external view returns (UserHistory[] memory, uint256) {
uint256 length = _limit;
uint256[] memory bettedRounds = bhavishPredictionStorage.getUserRounds(_user);
if (length > bettedRounds.length - _index) length = bettedRounds.length - _index;
UserHistory[] memory histories = new UserHistory[](length);
for (uint256 i = 0; i < length; i++) {
BetInfo memory betInfo = bhavishPredictionStorage.getBetInfo(bettedRounds[_index + i], _user);
Round memory round = bhavishPredictionStorage.getPredictionRound(bettedRounds[_index + i]);
histories[i].upPredictAmount = betInfo.upPredictAmount;
histories[i].downPredictAmount = betInfo.downPredictAmount;
histories[i].upPredictAmount = betInfo.upPredictAmount;
histories[i].claimed = betInfo.amountDispersed > 0 ? true : false;
histories[i].roundUpPredictAmount = round.upPredictAmount;
histories[i].roundDownPredictAmount = round.downPredictAmount;
histories[i].roundId = round.roundId;
histories[i].rewardAmount = round.rewardAmount;
histories[i].startPrice = round.startPrice;
histories[i].endPrice = round.endPrice;
histories[i].roundState = round.roundState;
uint256[] memory rounds = new uint256[](1);
rounds[0] = bettedRounds[_index + i];
if (round.roundState == RoundState.ENDED || round.roundState == RoundState.CANCELLED) {
histories[i].rewardReceived = betInfo.amountDispersed > 0
? betInfo.amountDispersed
: getRewards(rounds, _user);
} else {
histories[i].rewardReceived = 0;
}
histories[i].roundStartTimestamp = round.roundStartTimestamp;
histories[i].market = address(this);
histories[i].winStatus = round.endPrice > round.startPrice
? 0
: (round.endPrice < round.startPrice ? 1 : 2);
}
return (histories, _index + length);
}
function getUserInfo(
address _user,
uint256 _index,
uint256 _limit
) external view returns (UserInfo memory userInfo, uint256 nextIndex) {
uint256 length = _limit;
uint256[] memory bettedRounds = bhavishPredictionStorage.getUserRounds(_user);
if (length > bettedRounds.length - _index) length = bettedRounds.length - _index;
for (uint256 i = 0; i < length; i++) {
BetInfo memory betInfo = bhavishPredictionStorage.getBetInfo(bettedRounds[_index + i], _user);
Round memory round = bhavishPredictionStorage.getPredictionRound(bettedRounds[_index + i]);
userInfo.roundsPlayed += 1;
uint256[] memory rounds = new uint256[](1);
rounds[0] = bettedRounds[i];
userInfo.bettedAmount += (betInfo.upPredictAmount + betInfo.downPredictAmount);
if (round.endPrice > round.startPrice) {
if (betInfo.upPredictAmount > 0) {
userInfo.roundsWon += 1;
userInfo.netWinnings += betInfo.amountDispersed > 0
? betInfo.amountDispersed
: getRewards(rounds, _user);
} else {
userInfo.roundsLost += 1;
userInfo.netLosses += betInfo.downPredictAmount;
}
} else if (round.endPrice < round.startPrice) {
if (betInfo.downPredictAmount > 0) {
userInfo.roundsWon += 1;
userInfo.netWinnings += betInfo.amountDispersed > 0
? betInfo.amountDispersed
: getRewards(rounds, _user);
} else {
userInfo.roundsLost += 1;
userInfo.netLosses += betInfo.upPredictAmount;
}
}
}
userInfo.roundsDraw = userInfo.roundsPlayed - userInfo.roundsWon - userInfo.roundsLost;
userInfo.winRate = (userInfo.roundsWon * 100000) / userInfo.roundsPlayed; // allowing 3 decimal places
nextIndex = _index + length;
}
}// SPDX-License-Identifier: BSD-4-Clause
pragma solidity ^0.8.13;
import { AccessControl } from "@openzeppelin/contracts/access/AccessControl.sol";
import { Address } from "@openzeppelin/contracts/utils/Address.sol";
import { IBhavishPrediction } from "../../Interface/IBhavishPrediction.sol";
contract BhavishPredictionStorage is AccessControl {
using Address for address;
bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE");
mapping(uint256 => IBhavishPrediction.Round) public rounds;
mapping(uint256 => mapping(address => IBhavishPrediction.BetInfo)) public ledger;
mapping(address => uint256[]) public userRounds;
mapping(uint256 => address[]) public usersInRounds;
uint256 public latestRoundId;
modifier onlyManager(address _address) {
require(hasRole(MANAGER_ROLE, _address), "caller has no access to the method");
_;
}
constructor() {
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
}
function setManager(address _address) external {
require(_address != address(0) && _address.isContract(), "Invalid manager address");
grantRole(MANAGER_ROLE, _address);
}
function createPredictionRound(IBhavishPrediction.Round memory round) external onlyManager(msg.sender) {
rounds[round.roundId] = round;
latestRoundId = round.roundId;
}
function updatePredictionRound(IBhavishPrediction.Round memory round) external onlyManager(msg.sender) {
require(rounds[round.roundId].roundId != 0, "Cannot overwrite non existing round");
rounds[round.roundId] = round;
}
function getUsersInRounds(uint256 _predictRoundId) external view returns (address[] memory userAddresses) {
userAddresses = usersInRounds[_predictRoundId];
}
function getPredictionRound(uint256 roundId) external view returns (IBhavishPrediction.Round memory round) {
round = rounds[roundId];
}
function getArrayRounds(uint256 from, uint256 to)
external
view
returns (IBhavishPrediction.Round[] memory arrayOfRounds)
{
require(to <= latestRoundId, "Index out of bound");
require(from < to, "From < To");
uint256 len = to - from + 1;
arrayOfRounds = new IBhavishPrediction.Round[](len);
for (uint256 i = 0; i < len; i++) {
arrayOfRounds[i] = rounds[from];
from += 1;
}
}
function setRoundState(
uint256 roundId,
IBhavishPrediction.RoundState state,
uint256 price,
bool start
) external onlyManager(msg.sender) {
IBhavishPrediction.Round storage round = rounds[roundId];
round.roundState = state;
if (start) round.startPrice = price;
else round.endPrice = price;
}
function cancelRound(uint256 roundId) external onlyManager(msg.sender) {
IBhavishPrediction.Round storage round = rounds[roundId];
round.roundState = IBhavishPrediction.RoundState.CANCELLED;
}
function setRewardAmountForRound(
uint256 roundId,
uint256 rewardAmount,
uint256 rewardBaseCalAmount
) external onlyManager(msg.sender) {
IBhavishPrediction.Round storage round = rounds[roundId];
round.rewardAmount = rewardAmount;
round.rewardBaseCalAmount = rewardBaseCalAmount;
}
function setAmount(
uint256 roundId,
uint256 amount,
bool directionUp
) external onlyManager(msg.sender) {
IBhavishPrediction.Round storage round = rounds[roundId];
round.totalAmount = round.totalAmount + amount;
if (directionUp) round.upPredictAmount += amount;
else round.downPredictAmount += amount;
}
function createBet(
IBhavishPrediction.BetInfo memory betInfo,
uint256 roundId,
address userAddress
) external onlyManager(msg.sender) {
ledger[roundId][userAddress] = betInfo;
}
function getBetInfo(uint256 roundId, address userAddress)
external
view
returns (IBhavishPrediction.BetInfo memory betInfo)
{
betInfo = ledger[roundId][userAddress];
}
function setBetAmountDispersed(
uint256 roundId,
address userAddress,
uint256 amountDispersed
) external onlyManager(msg.sender) {
IBhavishPrediction.BetInfo storage betInfo = ledger[roundId][userAddress];
betInfo.amountDispersed += amountDispersed;
}
function setBetInfo(
uint256 amount,
uint256 roundId,
address userAddress,
bool directionUp
) external onlyManager(msg.sender) {
IBhavishPrediction.BetInfo storage betInfo = ledger[roundId][userAddress];
if (directionUp) betInfo.upPredictAmount += amount;
else betInfo.downPredictAmount += amount;
}
function setLedgerInfo(address userAddress, uint256 roundId) external onlyManager(msg.sender) {
userRounds[userAddress].push(roundId);
usersInRounds[roundId].push(userAddress);
}
function getUserRounds(address userAddress) external view returns (uint256[] memory) {
return userRounds[userAddress];
}
function getUserInRounds(uint256 roundId) external view returns (address[] memory) {
return usersInRounds[roundId];
}
}// SPDX-License-Identifier: BSD-4-Clause
pragma solidity ^0.8.13;
import {
AbstractPrediction,
IBhavishAdministrator,
IPriceManager,
BhavishPredictionStorage
} from "../AbstractPrediction.sol";
/**
* @title BhavishPrediction
*/
abstract contract AbstractCP is AbstractPrediction {
constructor(
uint256 _minPredictAmount,
uint256 _treasuryFee,
IBhavishAdministrator _bhavishAdmin,
IPriceManager _bhavishPriceManager,
BhavishPredictionStorage _bhavishPredictionStorage,
uint256 _roundTime,
bytes32 _underlying,
bytes32 _strike
)
AbstractPrediction(
_minPredictAmount,
_treasuryFee,
_bhavishAdmin,
_bhavishPriceManager,
_bhavishPredictionStorage,
_roundTime,
_underlying,
_strike
)
{}
/**
* @notice Create Round Zero round
* @dev callable by Operator
* @param _roundzeroStartTimestamp round zero round start timestamp
*/
function createPredictionMarket(uint256 _roundzeroStartTimestamp)
external
override
whenNotPaused
onlyOperator(msg.sender)
{
require(!marketStatus.createPredictionMarketOnce, "Can only run roundzeroCreateRound once");
currentRoundId = currentRoundId + 1;
roundzeroStartTimestamp = _roundzeroStartTimestamp;
_createRound(currentRoundId, _roundzeroStartTimestamp);
marketStatus.createPredictionMarketOnce = true;
//create next 3 rounds to be able to bet by users
_createRound(currentRoundId + 1, roundzeroStartTimestamp + roundTime);
_createRound(currentRoundId + 2, roundzeroStartTimestamp + roundTime + roundTime);
_createRound(currentRoundId + 3, roundzeroStartTimestamp + roundTime + roundTime + roundTime);
}
/**
* @notice Execute round
* @dev Callable by Operator
*/
function executeRound() external override whenNotPaused {
require(
marketStatus.createPredictionMarketOnce && marketStatus.startPredictionMarketOnce,
"Can only run after roundzeroStartRound"
);
Round memory curRound = bhavishPredictionStorage.getPredictionRound(currentRoundId);
Round memory roundPlusThree = bhavishPredictionStorage.getPredictionRound(currentRoundId + 3);
// currentRoundId refers to current round n
// fetch price to end current round and start new round
(uint256 price, ) = bhavishPriceManager.getPrice(
assetPair.underlying,
assetPair.strike,
curRound.roundEndTimestamp
);
// End and Disperse current round
if (curRound.roundState != RoundState.CANCELLED && price != 0) {
_endRound(currentRoundId, price);
_calculateRewards(currentRoundId);
} else if (curRound.roundState != RoundState.CANCELLED && price == 0) {
_cancelRound(currentRoundId);
}
// Start next round
_startRound(currentRoundId + 1, price);
// Create a new round n+3
_createRound(currentRoundId + 4, roundPlusThree.roundEndTimestamp);
// Point currentRoundId to next round
currentRoundId = currentRoundId + 1;
}
/**
* @notice Execute round
* @dev Callable by Operator
*/
function executeRound(uint256 _price) external override whenNotPaused onlyOperator(msg.sender) {
require(
marketStatus.createPredictionMarketOnce && marketStatus.startPredictionMarketOnce,
"Can only run after roundzeroStartRound"
);
Round memory curRound = bhavishPredictionStorage.getPredictionRound(currentRoundId);
Round memory roundPlusThree = bhavishPredictionStorage.getPredictionRound(currentRoundId + 3);
// End and Disperse current round
if (curRound.roundState != RoundState.CANCELLED && _price != 0) {
_endRound(currentRoundId, _price);
_calculateRewards(currentRoundId);
} else if (curRound.roundState != RoundState.CANCELLED && _price == 0) {
_cancelRound(currentRoundId);
}
// Start next round
_startRound(currentRoundId + 1, _price);
// Create a new round n+3
_createRound(currentRoundId + 4, roundPlusThree.roundEndTimestamp);
// Point currentRoundId to next round
currentRoundId = currentRoundId + 1;
}
}// SPDX-License-Identifier: BSD-4-Clause
pragma solidity ^0.8.13;
/**
* @title IBhavishAdministrator
*/
interface IBhavishAdministrator {
/**
* @dev Emitted when Treasury is claimed by the admin
* @param admin Address of the admin
* @param amount Amount claimed by the admin
*/
event TreasuryClaim(address indexed admin, uint256 amount);
/**
* @dev Claim the treasury amount. Can be performed only by admin
*/
function claimTreasury() external;
}// SPDX-License-Identifier: BSD-4-Clause
pragma solidity ^0.8.13;
interface IBhavishPrediction {
enum RoundState {
CREATED,
STARTED,
ENDED,
CANCELLED
}
struct Round {
uint256 roundId;
RoundState roundState;
uint256 upPredictAmount;
uint256 downPredictAmount;
uint256 totalAmount;
uint256 rewardBaseCalAmount;
uint256 rewardAmount;
uint256 startPrice;
uint256 endPrice;
uint256 roundStartTimestamp;
uint256 roundEndTimestamp;
}
struct BetInfo {
uint256 upPredictAmount;
uint256 downPredictAmount;
uint256 amountDispersed;
}
struct AssetPair {
bytes32 underlying;
bytes32 strike;
}
struct PredictionMarketStatus {
bool startPredictionMarketOnce;
bool createPredictionMarketOnce;
}
struct UserHistory {
uint256 upPredictAmount;
uint256 downPredictAmount;
uint256 rewardReceived;
bool claimed;
uint256 roundStartTimestamp;
uint256 roundId;
uint256 roundUpPredictAmount;
uint256 roundDownPredictAmount;
uint256 rewardAmount;
uint256 startPrice;
uint256 endPrice;
IBhavishPrediction.RoundState roundState;
uint256 winStatus;
address market;
}
struct UserInfo {
uint256 roundsWon;
uint256 roundsLost;
uint256 roundsPlayed;
uint256 roundsDraw;
uint256 winRate;
uint256 netWinnings;
uint256 netLosses;
uint256 bettedAmount;
}
/**
* @notice Create Round Zero round
* @dev callable by Operator
* @param _roundzeroStartTimestamp: round zero round start timestamp
*/
function createPredictionMarket(uint256 _roundzeroStartTimestamp) external;
/**
* @notice Start Zero round
* @dev callable by Operator
*/
function startPredictionMarket() external;
/**
* @notice Start Zero round
* @dev callable by Operator
*/
function startPredictionMarket(uint256 price) external;
/**
* @notice Execute round
* @dev Callable by Operator
*/
function executeRound() external;
/**
* @notice Execute round
* @dev Callable by Operator
*/
function executeRound(uint256 price) external;
function getCurrentRoundDetails() external view returns (IBhavishPrediction.Round memory);
function refundUsers(uint256 _predictRoundId, address userAddress) external;
function getAverageBetAmount(uint256[] calldata roundIds, address userAddress) external returns (uint256);
}// SPDX-License-Identifier: BSD-4-Clause
pragma solidity ^0.8.13;
import "./IBhavishPrediction.sol";
interface IBhavishPredictionNative is IBhavishPrediction {
struct SwapParams {
uint256 slippage;
bytes32 toAsset;
bool convert;
}
/**
* @notice Bet Bull position
* @param roundId: Round Id
* @param userAddress: Address of the user
*/
function predictUp(uint256 roundId, address userAddress) external payable;
/**
* @notice Bet Bear position
* @param roundId: Round Id
* @param userAddress: Address of the user
*/
function predictDown(uint256 roundId, address userAddress) external payable;
function claim(
uint256[] calldata _roundIds,
address _userAddress,
SwapParams memory _swapParams
) external returns (uint256);
}// SPDX-License-Identifier: BSD-4-Clause
pragma solidity ^0.8.13;
interface IBhavishSwap {
struct SwapStruct {
uint256 amountIn;
uint256 deadline;
bytes32 fromAsset;
bytes32 toAsset;
}
function swapExactETHForTokens(
SwapStruct memory _swapStruct,
address to,
uint256 slippage
) external payable returns (uint256[] memory amounts);
function swapExactTokensForETH(
SwapStruct memory _swapStruct,
address to,
uint256 slippage
) external returns (uint256[] memory amounts);
}// SPDX-License-Identifier: BSD-4-Clause
pragma solidity ^0.8.13;
interface IPriceManager {
/**
* @dev Emitted when the new Oracle aggregator data has been added.
* @param _underlying Address of the underlying asset.
* @param _strike Address of the strike asset.
* @param _bhavishAggregator Address of the bhavish aggregator.
* @param _aggregator Address of the aggregator.
*/
event AddAssetPairAggregator(
bytes32 indexed _underlying,
bytes32 indexed _strike,
address _bhavishAggregator,
address _aggregator
);
/**
* @notice Function to add the price for an underlying, strike asset pair
* @param _underlying Underlying Asset
* @param _strike Strike Asset
* @param _aggregator Address of the aggregator.
*/
function setPairContract(
bytes32 _underlying,
bytes32 _strike,
address _aggregator
) external;
/**
* @notice Function to get the price for an underlying asset
* @param _underlying Underlying Asset
* @param _strike Strike Asset
* @param _timestamp Timestamp
* @return price asset price
* @return decimals asset price decimals
*/
function getPrice(
bytes32 _underlying,
bytes32 _strike,
uint256 _timestamp
) external view returns (uint256 price, uint8 decimals);
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"uint256","name":"_minPredictAmount","type":"uint256"},{"internalType":"uint256","name":"_treasuryFee","type":"uint256"},{"internalType":"contract IBhavishAdministrator","name":"_bhavishAdmin","type":"address"},{"internalType":"contract IPriceManager","name":"_bhavishPriceManager","type":"address"},{"internalType":"contract BhavishPredictionStorage","name":"_bhavishPredictionStorage","type":"address"},{"internalType":"contract IBhavishSwap","name":"_bhavishSwap","type":"address"},{"internalType":"uint256","name":"_roundTime","type":"uint256"},{"internalType":"bytes32","name":"_underlying","type":"bytes32"},{"internalType":"bytes32","name":"_strike","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"roundId","type":"uint256"}],"name":"CancelRound","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"uint256","name":"roundId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"roundId","type":"uint256"}],"name":"CreateRound","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"roundId","type":"uint256"}],"name":"EndRound","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"}],"name":"NewAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_sdk","type":"address"}],"name":"NewBhvaishSDK","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"minPredictAmount","type":"uint256"}],"name":"NewMinPredictAmount","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"}],"name":"NewOperator","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"treasuryFee","type":"uint256"}],"name":"NewTreasuryFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultDiscountPerc","type":"uint256"}],"name":"NewVaultDiscountPercentage","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"currentRoundId","type":"uint256"}],"name":"PausedMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"uint256","name":"roundId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PredictDown","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"uint256","name":"roundId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PredictUp","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"roundId","type":"uint256"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"refundDispersed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Refund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"roundId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewardBaseCalAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewardAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"treasuryAmount","type":"uint256"}],"name":"RewardsCalculated","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":true,"internalType":"uint256","name":"roundId","type":"uint256"}],"name":"StartRound","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"bhavishAdmin","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferToAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"currentRoundId","type":"uint256"}],"name":"UnPausedMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TREASURY_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"roundId","type":"uint256"},{"internalType":"enum IBhavishPrediction.RoundState","name":"roundState","type":"uint8"},{"internalType":"uint256","name":"upPredictAmount","type":"uint256"},{"internalType":"uint256","name":"downPredictAmount","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"},{"internalType":"uint256","name":"rewardBaseCalAmount","type":"uint256"},{"internalType":"uint256","name":"rewardAmount","type":"uint256"},{"internalType":"uint256","name":"startPrice","type":"uint256"},{"internalType":"uint256","name":"endPrice","type":"uint256"},{"internalType":"uint256","name":"roundStartTimestamp","type":"uint256"},{"internalType":"uint256","name":"roundEndTimestamp","type":"uint256"}],"internalType":"struct IBhavishPrediction.Round","name":"_round","type":"tuple"},{"components":[{"internalType":"uint256","name":"upPredictAmount","type":"uint256"},{"internalType":"uint256","name":"downPredictAmount","type":"uint256"},{"internalType":"uint256","name":"amountDispersed","type":"uint256"}],"internalType":"struct IBhavishPrediction.BetInfo","name":"_betInfo","type":"tuple"}],"name":"_claimable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"addVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"assetPair","outputs":[{"internalType":"bytes32","name":"underlying","type":"bytes32"},{"internalType":"bytes32","name":"strike","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bhavishAdmin","outputs":[{"internalType":"contract IBhavishAdministrator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bhavishPredictionStorage","outputs":[{"internalType":"contract BhavishPredictionStorage","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bhavishPriceManager","outputs":[{"internalType":"contract IPriceManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bhavishSDK","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bhavishSwap","outputs":[{"internalType":"contract IBhavishSwap","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_roundIds","type":"uint256[]"},{"internalType":"address","name":"_userAddress","type":"address"},{"components":[{"internalType":"uint256","name":"slippage","type":"uint256"},{"internalType":"bytes32","name":"toAsset","type":"bytes32"},{"internalType":"bool","name":"convert","type":"bool"}],"internalType":"struct IBhavishPredictionNative.SwapParams","name":"_swapParams","type":"tuple"}],"name":"claim","outputs":[{"internalType":"uint256","name":"reward","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_roundzeroStartTimestamp","type":"uint256"}],"name":"createPredictionMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentRoundId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"executeRound","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"executeRound","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"roundIds","type":"uint256[]"},{"internalType":"address","name":"userAddress","type":"address"}],"name":"getAverageBetAmount","outputs":[{"internalType":"uint256","name":"betAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentRoundDetails","outputs":[{"components":[{"internalType":"uint256","name":"roundId","type":"uint256"},{"internalType":"enum IBhavishPrediction.RoundState","name":"roundState","type":"uint8"},{"internalType":"uint256","name":"upPredictAmount","type":"uint256"},{"internalType":"uint256","name":"downPredictAmount","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"},{"internalType":"uint256","name":"rewardBaseCalAmount","type":"uint256"},{"internalType":"uint256","name":"rewardAmount","type":"uint256"},{"internalType":"uint256","name":"startPrice","type":"uint256"},{"internalType":"uint256","name":"endPrice","type":"uint256"},{"internalType":"uint256","name":"roundStartTimestamp","type":"uint256"},{"internalType":"uint256","name":"roundEndTimestamp","type":"uint256"}],"internalType":"struct IBhavishPrediction.Round","name":"round","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"roundIds","type":"uint256[]"},{"internalType":"address","name":"userAddress","type":"address"}],"name":"getRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"getUserHistory","outputs":[{"components":[{"internalType":"uint256","name":"upPredictAmount","type":"uint256"},{"internalType":"uint256","name":"downPredictAmount","type":"uint256"},{"internalType":"uint256","name":"rewardReceived","type":"uint256"},{"internalType":"bool","name":"claimed","type":"bool"},{"internalType":"uint256","name":"roundStartTimestamp","type":"uint256"},{"internalType":"uint256","name":"roundId","type":"uint256"},{"internalType":"uint256","name":"roundUpPredictAmount","type":"uint256"},{"internalType":"uint256","name":"roundDownPredictAmount","type":"uint256"},{"internalType":"uint256","name":"rewardAmount","type":"uint256"},{"internalType":"uint256","name":"startPrice","type":"uint256"},{"internalType":"uint256","name":"endPrice","type":"uint256"},{"internalType":"enum IBhavishPrediction.RoundState","name":"roundState","type":"uint8"},{"internalType":"uint256","name":"winStatus","type":"uint256"},{"internalType":"address","name":"market","type":"address"}],"internalType":"struct IBhavishPrediction.UserHistory[]","name":"","type":"tuple[]"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"getUserInfo","outputs":[{"components":[{"internalType":"uint256","name":"roundsWon","type":"uint256"},{"internalType":"uint256","name":"roundsLost","type":"uint256"},{"internalType":"uint256","name":"roundsPlayed","type":"uint256"},{"internalType":"uint256","name":"roundsDraw","type":"uint256"},{"internalType":"uint256","name":"winRate","type":"uint256"},{"internalType":"uint256","name":"netWinnings","type":"uint256"},{"internalType":"uint256","name":"netLosses","type":"uint256"},{"internalType":"uint256","name":"bettedAmount","type":"uint256"}],"internalType":"struct IBhavishPrediction.UserInfo","name":"userInfo","type":"tuple"},{"internalType":"uint256","name":"nextIndex","type":"uint256"}],"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":"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":"address","name":"","type":"address"}],"name":"isVault","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketStatus","outputs":[{"internalType":"bool","name":"startPredictionMarketOnce","type":"bool"},{"internalType":"bool","name":"createPredictionMarketOnce","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minPredictAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_predictRoundId","type":"uint256"},{"internalType":"address","name":"_userAddress","type":"address"}],"name":"predictDown","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_predictRoundId","type":"uint256"},{"internalType":"address","name":"_userAddress","type":"address"}],"name":"predictUp","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_predictRoundId","type":"uint256"},{"internalType":"address","name":"userAddress","type":"address"}],"name":"refundUsers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"removeOperator","outputs":[],"stateMutability":"nonpayable","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":[],"name":"roundTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"roundzeroStartTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IBhavishAdministrator","name":"_bhavishAdministrator","type":"address"}],"name":"setBhavishAdministrator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_sdk","type":"address"}],"name":"setBhavishSDK","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minPredictAmount","type":"uint256"}],"name":"setMinPredictAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"setOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_roundTime","type":"uint256"}],"name":"setRoundTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_treasuryFee","type":"uint256"}],"name":"setTreasuryFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_discountPerc","type":"uint256"}],"name":"setVaultDiscountPerc","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"startPredictionMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startPredictionMarket","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":"_amount","type":"uint256"}],"name":"transferToAdmin","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"treasuryAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasuryFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IBhavishSwap","name":"_swap","type":"address"}],"name":"updateBhavishSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vaultDiscountPerc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60806040526003600b553480156200001657600080fd5b5060405162005e8838038062005e888339810160408190526200003991620003e3565b6001805460ff19168155600255838989898989888888878787878787878787620000aa5760405162461bcd60e51b815260206004820152601a60248201527f496e76616c6964204d696e205072656469637420616d6f756e7400000000000060448201526064015b60405180910390fd5b600087118015620000bb5750606487105b620001095760405162461bcd60e51b815260206004820152601860248201527f54726561737572792066656520697320746f6f206869676800000000000000006044820152606401620000a1565b8260001080156200011d5750620151808311155b620001825760405162461bcd60e51b815260206004820152602e60248201527f526f756e642054696d652073686f756c64206265206265747765656e2031207360448201526d656320746f20333630302073656360901b6064820152608401620000a1565b600988905560078790556064600855600f80546001600160a01b038089166001600160a01b031992831617909255601080548884169083161790556011805492871692909116821790556040805180820182528481526020808201859052600d869055600e859055600487815583516311a8f41360e01b815293519294936311a8f41393818301939290918290030181865afa15801562000227573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200024d91906200047e565b6003556200025d6000336200030b565b50505050505050505050505050505050506200028d816001600160a01b03166200031b60201b620031101760201c565b620002db5760405162461bcd60e51b815260206004820152601960248201527f53776170706572206973206e6f74206120636f6e7472616374000000000000006044820152606401620000a1565b601380546001600160a01b0319166001600160a01b03929092169190911790555062000498975050505050505050565b6200031782826200032a565b5050565b6001600160a01b03163b151590565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1662000317576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620003863390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6001600160a01b0381168114620003e057600080fd5b50565b60008060008060008060008060006101208a8c0312156200040357600080fd5b8951985060208a0151975060408a01516200041e81620003ca565b60608b01519097506200043181620003ca565b60808b01519096506200044481620003ca565b60a08b01519095506200045781620003ca565b8094505060c08a0151925060e08a015191506101008a015190509295985092959850929598565b6000602082840312156200049157600080fd5b5051919050565b6159e080620004a86000396000f3fe6080604052600436106103545760003560e01c80638456cb59116101c6578063e0e081d7116100f7578063f4d508ec11610095578063f7b188a51161006f578063f7b188a514610a2b578063fa65cb0414610a40578063fb2f897a14610a60578063fc572b1814610a8057600080fd5b8063f4d508ec1461095f578063f5032980146109e9578063f5b541a614610a0957600080fd5b8063ec87621c116100d1578063ec87621c146108e0578063ee5f8c8f14610914578063efc3b2ea1461092a578063f2b3c8091461094a57600080fd5b8063e0e081d714610873578063e44bb72f146108ad578063e8712bd4146108c057600080fd5b8063a357a62011610164578063b6705a551161013e578063b6705a55146107fd578063bd9de03c1461081d578063cc32d1761461083d578063d547741f1461085357600080fd5b8063a357a6201461078f578063ac8a584a146107bd578063b3ab15fb146107dd57600080fd5b80639cbe5efd116101a05780639cbe5efd14610724578063a20037341461073a578063a217fddf1461075a578063a23e98841461076f57600080fd5b80638456cb59146106cd57806391d14854146106e25780639bb6eb701461070257600080fd5b8063445769cd116102a0578063733436201161023e578063783cf33211610218578063783cf33214610662578063795c29601461068257806379905dd5146106a25780637b3205f5146106b857600080fd5b8063733436201461060d57806377e0181f1461062d57806377e741c71461064257600080fd5b80635a9aa9571161027a5780635a9aa9571461058f5780635c975abb146105a5578063652b9b41146105bd5780636d27c9db146105ed57600080fd5b8063445769cd1461052f5780634b14c3d41461054f57806357957f691461056f57600080fd5b80632f2ff15d1161030d57806335538b69116102e757806335538b69146104b957806336568abe146104d9578063368acb09146104f957806340a201381461050f57600080fd5b80632f2ff15d1461044b578063313ce5671461046b578063325f700e1461048157600080fd5b806301ffc9a71461036057806309fffec01461039557806310082c75146103aa5780631c389c28146103da578063248a9ca3146103ed578063256b5a021461042b57600080fd5b3661035b57005b600080fd5b34801561036c57600080fd5b5061038061037b366004614ccb565b610a96565b60405190151581526020015b60405180910390f35b6103a86103a3366004614cf5565b610acd565b005b3480156103b657600080fd5b50600d54600e546103c5919082565b6040805192835260208301919091520161038c565b6103a86103e8366004614d33565b610bef565b3480156103f957600080fd5b5061041d610408366004614cf5565b60009081526020819052604090206001015490565b60405190815260200161038c565b34801561043757600080fd5b506103a8610446366004614d63565b610c30565b34801561045757600080fd5b506103a8610466366004614d33565b610cc4565b34801561047757600080fd5b5061041d600b5481565b34801561048d57600080fd5b50600f546104a1906001600160a01b031681565b6040516001600160a01b03909116815260200161038c565b3480156104c557600080fd5b506103a86104d4366004614cf5565b610cee565b3480156104e557600080fd5b506103a86104f4366004614d33565b610e4a565b34801561050557600080fd5b5061041d600a5481565b34801561051b57600080fd5b506103a861052a366004614d63565b610ec4565b34801561053b57600080fd5b506103a861054a366004614cf5565b610f0f565b34801561055b57600080fd5b506013546104a1906001600160a01b031681565b34801561057b57600080fd5b5061041d61058a366004614e59565b610fc4565b34801561059b57600080fd5b5061041d60055481565b3480156105b157600080fd5b5060015460ff16610380565b3480156105c957600080fd5b506103806105d8366004614d63565b60126020526000908152604090205460ff1681565b3480156105f957600080fd5b506103a8610608366004614cf5565b611153565b34801561061957600080fd5b506103a8610628366004614d33565b611249565b34801561063957600080fd5b506103a86114ed565b34801561064e57600080fd5b506103a861065d366004614cf5565b611659565b34801561066e57600080fd5b506103a861067d366004614cf5565b61171a565b34801561068e57600080fd5b5061041d61069d366004614ef8565b611950565b3480156106ae57600080fd5b5061041d60085481565b3480156106c457600080fd5b506103a8611a48565b3480156106d957600080fd5b506103a8611cd5565b3480156106ee57600080fd5b506103806106fd366004614d33565b611e84565b34801561070e57600080fd5b50610717611ead565b60405161038c9190614f87565b34801561073057600080fd5b5061041d60035481565b34801561074657600080fd5b5061038061075536600461505c565b611f87565b34801561076657600080fd5b5061041d600081565b34801561077b57600080fd5b506103a861078a366004614d63565b612002565b34801561079b57600080fd5b506107af6107aa36600461511a565b6120a4565b60405161038c92919061514f565b3480156107c957600080fd5b506103a86107d8366004614d63565b6126c5565b3480156107e957600080fd5b506103a86107f8366004614d63565b612705565b34801561080957600080fd5b506103a8610818366004614cf5565b6127cc565b34801561082957600080fd5b50600c546104a1906001600160a01b031681565b34801561084957600080fd5b5061041d60075481565b34801561085f57600080fd5b506103a861086e366004614d33565b612882565b34801561087f57600080fd5b506006546108969060ff8082169161010090041682565b60408051921515835290151560208301520161038c565b6103a86108bb366004614d33565b6128a7565b3480156108cc57600080fd5b506011546104a1906001600160a01b031681565b3480156108ec57600080fd5b5061041d7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b0881565b34801561092057600080fd5b5061041d60045481565b34801561093657600080fd5b506010546104a1906001600160a01b031681565b34801561095657600080fd5b5061041d606481565b34801561096b57600080fd5b5061097f61097a36600461511a565b6128df565b60405161038c929190600061012082019050835182526020840151602083015260408401516040830152606084015160608301526080840151608083015260a084015160a083015260c084015160c083015260e084015160e0830152826101008301529392505050565b3480156109f557600080fd5b506103a8610a04366004614d63565b612d0f565b348015610a1557600080fd5b5061041d60008051602061598b83398151915281565b348015610a3757600080fd5b506103a8612dcb565b348015610a4c57600080fd5b506103a8610a5b366004614cf5565b612ebf565b348015610a6c57600080fd5b5061041d610a7b36600461525e565b612f78565b348015610a8c57600080fd5b5061041d60095481565b60006001600160e01b03198216637965db0b60e01b1480610ac757506301ffc9a760e01b6001600160e01b03198316145b92915050565b6002805403610af75760405162461bcd60e51b8152600401610aee90615306565b60405180910390fd5b6002805533610b07600082611e84565b610b235760405162461bcd60e51b8152600401610aee9061533d565b600a54821115610b755760405162461bcd60e51b815260206004820152601c60248201527f5472616e7366657220616d6f756e7420697320746f6f206c61726765000000006044820152606401610aee565b81600a6000828254610b879190615381565b9091555050600f546001600160a01b0316610ba2818461311f565b806001600160a01b03167fc9262544ea8cacb7a3eea4ea7b4023ea10ac8bc73701610edba13308190f9cb184604051610bdd91815260200190565b60405180910390a25050600160025550565b610bf7613129565b6002805403610c185760405162461bcd60e51b8152600401610aee90615306565b60028055610c27828234613171565b50506001600255565b33610c3c600082611e84565b610c585760405162461bcd60e51b8152600401610aee9061533d565b6001600160a01b0382163b610c9f5760405162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081d985d5b1d609a1b6044820152606401610aee565b506001600160a01b03166000908152601260205260409020805460ff19166001179055565b600082815260208190526040902060010154610cdf81613519565b610ce98383613526565b505050565b610cf6613129565b33610d0f60008051602061598b83398151915282611e84565b610d2b5760405162461bcd60e51b8152600401610aee90615398565b600654610100900460ff1615610d925760405162461bcd60e51b815260206004820152602660248201527f43616e206f6e6c792072756e20726f756e647a65726f437265617465526f756e60448201526564206f6e636560d01b6064820152608401610aee565b600354610da09060016153cf565b60038190556005839055610db490836135aa565b6006805461ff001916610100179055600354610dea90610dd59060016153cf565b600454600554610de591906153cf565b6135aa565b610e176003546002610dfc91906153cf565b600454600554610e0d9082906153cf565b610de591906153cf565b610e466003546003610e2991906153cf565b6004546005548190610e3c9082906153cf565b610e0d91906153cf565b5050565b6001600160a01b0381163314610eba5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610aee565b610e468282613776565b33610ed0600082611e84565b610eec5760405162461bcd60e51b8152600401610aee9061533d565b50601380546001600160a01b0319166001600160a01b0392909216919091179055565b610f176137db565b33610f23600082611e84565b610f3f5760405162461bcd60e51b8152600401610aee9061533d565b60008211610f875760405162461bcd60e51b815260206004820152601560248201527404d757374206265207375706572696f7220746f203605c1b6044820152606401610aee565b60098290556040518281527f06a2e1014d8503fc3c899acda61fc50ab1918a70e8f904759a1f72f03bbd9cda906020015b60405180910390a15050565b60006002805403610fe75760405162461bcd60e51b8152600401610aee90615306565b60028055604080516020808702828101820190935286825261102692889188918291850190849080828437600092019190915250879250613824915050565b506040830151909150801561103b5750600081115b15611136576000604051806080016040528060008152602001600454600261106391906153e7565b61106d90426153cf565b8152644d4154494360d81b6020808301919091528581015160409283015260135486518351630c44410b60e41b815285516004820152928501516024840152928401516044830152606084015160648301526001600160a01b03888116608484015260a483019390935292935091169063c44410b090849060c40160006040518083038185885af1158015611106573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f1916820160405261112f9190810190615406565b5050611146565b8015611146576111468382613bb1565b6001600255949350505050565b61115b613129565b3361117460008051602061598b83398151915282611e84565b6111905760405162461bcd60e51b8152600401610aee90615398565b600654610100900460ff166111b75760405162461bcd60e51b8152600401610aee90615497565b60065460ff16156111da5760405162461bcd60e51b8152600401610aee906154eb565b60055442101561122c5760405162461bcd60e51b815260206004820152601d60248201527f526f756e642063616e6e6f742062652073746172746564206561726c790000006044820152606401610aee565b61123860035483613c54565b50506006805460ff19166001179055565b600280540361126a5760405162461bcd60e51b8152600401610aee90615306565b6002805560115460405163168a468560e11b8152600481018490526000916001600160a01b031690632d148d0a9060240161016060405180830381865afa1580156112b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112dd919061553b565b90506003816020015160038111156112f7576112f7614f4f565b146113445760405162461bcd60e51b815260206004820152601c60248201527f55736572206e6f7420656c696769626c6520666f7220726566756e64000000006044820152606401610aee565b601154604051630736449d60e11b8152600481018590526001600160a01b0384811660248301526000921690630e6c893a90604401606060405180830381865afa158015611396573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ba91906155d5565b905080604001516000146114095760405162461bcd60e51b81526020600482015260166024820152751499599d5b9908185b1c9958591e4818db185a5b595960521b6044820152606401610aee565b6020810151815160009161141c916153cf565b905080156114e15760115460405163720988c960e11b8152600481018790526001600160a01b038681166024830152604482018490529091169063e413119290606401600060405180830381600087803b15801561147957600080fd5b505af115801561148d573d6000803e3d6000fd5b5050505061149b8482613bb1565b604080518281524260208201526001600160a01b0386169187917faba4210cad11f1112f31ba136a61cdc0f6ab4c2b478da8c93eec1d9769e97a89910160405180910390a35b50506001600255505050565b6114f5613129565b3361150e60008051602061598b83398151915282611e84565b61152a5760405162461bcd60e51b8152600401610aee90615398565b600654610100900460ff166115515760405162461bcd60e51b8152600401610aee90615497565b60065460ff16156115745760405162461bcd60e51b8152600401610aee906154eb565b6005544210156115c65760405162461bcd60e51b815260206004820152601d60248201527f526f756e642063616e6e6f742062652073746172746564206561726c790000006044820152606401610aee565b601054600d54600e546005546040516319f59e5f60e01b81526004810193909352602483019190915260448201526000916001600160a01b0316906319f59e5f906064016040805180830381865afa158015611626573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164a9190615631565b50905061123860035482613c54565b6116616137db565b3361166d600082611e84565b6116895760405162461bcd60e51b8152600401610aee9061533d565b6000821180156116995750606482105b6116e55760405162461bcd60e51b815260206004820152601860248201527f54726561737572792066656520697320746f6f206869676800000000000000006044820152606401610aee565b60078290556040518281527f938d9272b26145999fe14f6124b73f122e1e023fc5de069c74ade1254408a97690602001610fb8565b611722613129565b3361173b60008051602061598b83398151915282611e84565b6117575760405162461bcd60e51b8152600401610aee90615398565b600654610100900460ff168015611770575060065460ff165b61178c5760405162461bcd60e51b8152600401610aee9061565c565b60115460035460405163168a468560e11b815260048101919091526000916001600160a01b031690632d148d0a9060240161016060405180830381865afa1580156117db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ff919061553b565b601154600380549293506000926001600160a01b0390921691632d148d0a9161182891906153cf565b6040518263ffffffff1660e01b815260040161184691815260200190565b61016060405180830381865afa158015611864573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611888919061553b565b90506003826020015160038111156118a2576118a2614f4f565b141580156118af57508315155b156118d0576118c060035485613e29565b6118cb600354613fee565b611904565b6003826020015160038111156118e8576118e8614f4f565b141580156118f4575083155b156119045761190460035461427b565b61191c600354600161191691906153cf565b85613c54565b611939600354600461192e91906153cf565b8261014001516135aa565b6003546119479060016153cf565b60035550505050565b6000805b83811015611a2d576011546000906001600160a01b0316630e6c893a878785818110611982576119826156a2565b90506020020135866040518363ffffffff1660e01b81526004016119b99291909182526001600160a01b0316602082015260400190565b606060405180830381865afa1580156119d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119fa91906155d5565b80516020820151919250611a0d916153cf565b611a1790846153cf565b9250508080611a25906156b8565b915050611954565b508215611a4157611a3e83826156d1565b90505b9392505050565b611a50613129565b600654610100900460ff168015611a69575060065460ff165b611a855760405162461bcd60e51b8152600401610aee9061565c565b60115460035460405163168a468560e11b815260048101919091526000916001600160a01b031690632d148d0a9060240161016060405180830381865afa158015611ad4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af8919061553b565b601154600380549293506000926001600160a01b0390921691632d148d0a91611b2191906153cf565b6040518263ffffffff1660e01b8152600401611b3f91815260200190565b61016060405180830381865afa158015611b5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b81919061553b565b601054600d54600e546101408601516040516319f59e5f60e01b81526004810193909352602483019190915260448201529192506000916001600160a01b03909116906319f59e5f906064016040805180830381865afa158015611be9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c0d9190615631565b509050600383602001516003811115611c2857611c28614f4f565b14158015611c3557508015155b15611c5657611c4660035482613e29565b611c51600354613fee565b611c8a565b600383602001516003811115611c6e57611c6e614f4f565b14158015611c7a575080155b15611c8a57611c8a60035461427b565b611ca26003546001611c9c91906153cf565b82613c54565b611cbf6003546004611cb491906153cf565b8361014001516135aa565b600354611ccd9060016153cf565b600355505050565b611cdd613129565b33611cf660008051602061598b83398151915282611e84565b611d125760405162461bcd60e51b8152600401610aee90615398565b611d1a6143ec565b6003545b601160009054906101000a90046001600160a01b03166001600160a01b03166311a8f4136040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9591906156f3565b8111611e455760115460405163168a468560e11b8152600481018390526000916001600160a01b031690632d148d0a9060240161016060405180830381865afa158015611de6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0a919061553b565b9050600381602001516003811115611e2457611e24614f4f565b14611e3257611e328261427b565b5080611e3d816156b8565b915050611d1e565b507fa382c86dbb1fba726013556ec174337b8f9ddac70b97ddb00d2e79e8b565d4f5600354604051611e7991815260200190565b60405180910390a150565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b611f0b6040805161016081019091526000808252602082019081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60115460035460405163168a468560e11b81526001600160a01b0390921691632d148d0a91611f409160040190815260200190565b61016060405180830381865afa158015611f5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f82919061553b565b905090565b8051600090151580611f9c5750602082015115155b8015611faa57506040820151155b8015611a4157508260e00151836101000151118015611fc95750815115155b80611fea57508260e00151836101000151108015611fea5750602082015115155b80611a415750505060e0810151610100909101511490565b3361200e600082611e84565b61202a5760405162461bcd60e51b8152600401610aee9061533d565b6001600160a01b0382163b6120815760405162461bcd60e51b815260206004820152601960248201527f4e6f7420426861766973682041646d696e6973747261746f72000000000000006044820152606401610aee565b50600f80546001600160a01b0319166001600160a01b0392909216919091179055565b601154604051630e9418a560e21b81526001600160a01b038581166004830152606092600092859284921690633a50629490602401600060405180830381865afa1580156120f6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261211e9190810190615406565b905085815161212d9190615381565b821115612144578581516121419190615381565b91505b60008267ffffffffffffffff81111561215f5761215f614dc5565b60405190808252806020026020018201604052801561219857816020015b612185614c49565b81526020019060019003908161217d5790505b50905060005b838110156126aa576011546000906001600160a01b0316630e6c893a856121c5858d6153cf565b815181106121d5576121d56156a2565b60200260200101518c6040518363ffffffff1660e01b815260040161220d9291909182526001600160a01b0316602082015260400190565b606060405180830381865afa15801561222a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224e91906155d5565b6011549091506000906001600160a01b0316632d148d0a86612270868e6153cf565b81518110612280576122806156a2565b60200260200101516040518263ffffffff1660e01b81526004016122a691815260200190565b61016060405180830381865afa1580156122c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122e8919061553b565b90508160000151848481518110612301576123016156a2565b602002602001015160000181815250508160200151848481518110612328576123286156a2565b60200260200101516020018181525050816000015184848151811061234f5761234f6156a2565b602090810291909101015152604082015161236b57600061236e565b60015b848481518110612380576123806156a2565b6020026020010151606001901515908115158152505080604001518484815181106123ad576123ad6156a2565b602002602001015160c001818152505080606001518484815181106123d4576123d46156a2565b602002602001015160e001818152505080600001518484815181106123fb576123fb6156a2565b602002602001015160a00181815250508060c00151848481518110612422576124226156a2565b60200260200101516101000181815250508060e0015184848151811061244a5761244a6156a2565b6020026020010151610120018181525050806101000151848481518110612473576124736156a2565b6020026020010151610140018181525050806020015184848151811061249b5761249b6156a2565b6020026020010151610160019060038111156124b9576124b9614f4f565b908160038111156124cc576124cc614f4f565b90525060408051600180825281830190925260009160208083019080368337019050509050856124fc858d6153cf565b8151811061250c5761250c6156a2565b602002602001015181600081518110612527576125276156a2565b602090810291909101015260028260200151600381111561254a5761254a614f4f565b148061256b575060038260200151600381111561256957612569614f4f565b145b156125b857600083604001511161258b57612586818d612f78565b612591565b82604001515b8585815181106125a3576125a36156a2565b602002602001015160400181815250506125dd565b60008585815181106125cc576125cc6156a2565b602002602001015160400181815250505b8161012001518585815181106125f5576125f56156a2565b6020026020010151608001818152505030858581518110612618576126186156a2565b60200260200101516101a001906001600160a01b031690816001600160a01b0316815250508160e001518261010001511161266b578160e001518261010001511061266457600261266e565b600161266e565b60005b60ff16858581518110612683576126836156a2565b602002602001015161018001818152505050505080806126a2906156b8565b91505061219e565b50806126b684896153cf565b94509450505050935093915050565b336126d1600082611e84565b6126ed5760405162461bcd60e51b8152600401610aee9061533d565b610e4660008051602061598b83398151915283612882565b33612711600082611e84565b61272d5760405162461bcd60e51b8152600401610aee9061533d565b6001600160a01b03821661277c5760405162461bcd60e51b815260206004820152601660248201527543616e6e6f74206265207a65726f206164647265737360501b6044820152606401610aee565b61279460008051602061598b83398151915283610cc4565b6040516001600160a01b038316907fda12ee837e6978172aaf54b16145ffe08414fd8710092ef033c71b8eb6ec189a90600090a25050565b6127d46137db565b336127e0600082611e84565b6127fc5760405162461bcd60e51b8152600401610aee9061533d565b606482111561284d5760405162461bcd60e51b815260206004820152601f60248201527f5661756c7420646973636f756e74207065726320697320746f6f2068696768006044820152606401610aee565b60088290556040518281527f1c3d6aca04a9d74c524b053538418e96eafc310c8d049c2a44f001d1b0c03fc390602001610fb8565b60008281526020819052604090206001015461289d81613519565b610ce98383613776565b6128af613129565b60028054036128d05760405162461bcd60e51b8152600401610aee90615306565b60028055610c27828234614440565b61292760405180610100016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b601154604051630e9418a560e21b81526001600160a01b0386811660048301526000928592849290911690633a50629490602401600060405180830381865afa158015612978573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526129a09190810190615406565b90508581516129af9190615381565b8211156129c6578581516129c39190615381565b91505b60005b82811015612cb0576011546000906001600160a01b0316630e6c893a846129f0858c6153cf565b81518110612a0057612a006156a2565b60200260200101518b6040518363ffffffff1660e01b8152600401612a389291909182526001600160a01b0316602082015260400190565b606060405180830381865afa158015612a55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a7991906155d5565b6011549091506000906001600160a01b0316632d148d0a85612a9b868d6153cf565b81518110612aab57612aab6156a2565b60200260200101516040518263ffffffff1660e01b8152600401612ad191815260200190565b61016060405180830381865afa158015612aef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b13919061553b565b9050600187604001818151612b2891906153cf565b90525060408051600180825281830190925260009160208083019080368337019050509050848481518110612b5f57612b5f6156a2565b602002602001015181600081518110612b7a57612b7a6156a2565b60200260200101818152505082602001518360000151612b9a91906153cf565b8860e001818151612bab91906153cf565b90525060e08201516101008301511115612c3f57825115612c1357600188600001818151612bd991906153cf565b9052506040830151612bf457612bef818c612f78565b612bfa565b82604001515b8860a001818151612c0b91906153cf565b905250612c9a565b600188602001818151612c2691906153cf565b905250602083015160c089018051612c0b9083906153cf565b8160e001518261010001511015612c9a57602083015115612c6d57600188600001818151612bd991906153cf565b600188602001818151612c8091906153cf565b905250825160c089018051612c969083906153cf565b9052505b5050508080612ca8906156b8565b9150506129c9565b50602084015184516040860151612cc79190615381565b612cd19190615381565b606085015260408401518451612cea90620186a06153e7565b612cf491906156d1565b6080850152612d0382876153cf565b92505050935093915050565b33612d1b600082611e84565b612d375760405162461bcd60e51b8152600401610aee9061533d565b6001600160a01b0382163b612d805760405162461bcd60e51b815260206004820152600f60248201526e696e76616c6964206164647265737360881b6044820152606401610aee565b600c80546001600160a01b0319166001600160a01b0384169081179091556040517f98902aabfcbed99d0d9769f20db2c97ad70f69f67ca8811518d37b9e590e0e8890600090a25050565b612dd36137db565b33612dec60008051602061598b83398151915282611e84565b612e085760405162461bcd60e51b8152600401610aee90615398565b6006805461ffff19169055601154604080516311a8f41360e01b815290516001600160a01b03909216916311a8f413916004808201926020929091908290030181865afa158015612e5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e8191906156f3565b600355612e8c6147d8565b7f0b0e422893e2219d69c6fba12911d3b270235e96e9753519998fc13013ebb2ae600354604051611e7991815260200190565b612ec76137db565b33612ee060008051602061598b83398151915282611e84565b612efc5760405162461bcd60e51b8152600401610aee90615398565b816000108015612f0f5750620151808211155b612f725760405162461bcd60e51b815260206004820152602e60248201527f526f756e642054696d652073686f756c64206265206265747765656e2031207360448201526d656320746f20333630302073656360901b6064820152608401610aee565b50600455565b600080805b84518110156131085760115485516000916001600160a01b031690632d148d0a90889085908110612fb057612fb06156a2565b60200260200101516040518263ffffffff1660e01b8152600401612fd691815260200190565b61016060405180830381865afa158015612ff4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613018919061553b565b60115487519192506000916001600160a01b0390911690630e6c893a90899086908110613047576130476156a2565b6020026020010151886040518363ffffffff1660e01b815260040161307f9291909182526001600160a01b0316602082015260400190565b606060405180830381865afa15801561309c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130c091906155d5565b90506130cc8282611f87565b6130d75750506130f6565b60006130e38383614811565b5090506130f081866153cf565b94505050505b80613100816156b8565b915050612f7d565b509392505050565b6001600160a01b03163b151590565b610e468282613bb1565b60015460ff161561316f5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610aee565b565b81336001600160a01b038216146131ac57600c546001600160a01b031633146131ac5760405162461bcd60e51b8152600401610aee9061570c565b60115460405163168a468560e11b8152600481018690526000916001600160a01b031690632d148d0a9060240161016060405180830381865afa1580156131f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061321b919061553b565b905060008160200151600381111561323557613235614f4f565b1480156132425750805115155b6132865760405162461bcd60e51b815260206004820152601560248201527442657420697320746f6f206561726c792f6c61746560581b6044820152606401610aee565b8061012001514211156132d35760405162461bcd60e51b81526020600482015260156024820152741c9bdd5b9908185b1c9958591e481cdd185c9d1959605a1b6044820152606401610aee565b6009548310156132f55760405162461bcd60e51b8152600401610aee90615734565b60115460405163ec4773a760e01b81526004810187905260248101859052600160448201526001600160a01b039091169063ec4773a790606401600060405180830381600087803b15801561334957600080fd5b505af115801561335d573d6000803e3d6000fd5b5050601154604051630736449d60e11b8152600481018990526001600160a01b038881166024830152600094509091169150630e6c893a90604401606060405180830381865afa1580156133b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133d991906155d5565b80519091501580156133ed57506020810151155b1561345957601154604051634a966a1b60e01b81526001600160a01b0387811660048301526024820189905290911690634a966a1b90604401600060405180830381600087803b15801561344057600080fd5b505af1158015613454573d6000803e3d6000fd5b505050505b6011546040516331e1f08360e11b815260048101869052602481018890526001600160a01b03878116604483015260016064830152909116906363c3e10690608401600060405180830381600087803b1580156134b557600080fd5b505af11580156134c9573d6000803e3d6000fd5b5050505085856001600160a01b03167f0bab430d5cfc26b856f9867d7019c5af92e6fb9f0eef60afadab9f0d53ff1fd38660405161350991815260200190565b60405180910390a3505050505050565b61352381336148f7565b50565b6135308282611e84565b610e46576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556135663390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60115460405163168a468560e11b8152600481018490526000916001600160a01b031690632d148d0a9060240161016060405180830381865afa1580156135f5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613619919061553b565b8051909150156136625760405162461bcd60e51b8152602060048201526014602482015273526f756e6420616c72656164792065786973747360601b6044820152606401610aee565b42600454836136719190615381565b10156136bf5760405162461bcd60e51b815260206004820152601760248201527f526f756e642074696d6520697320746f6f2073686f72740000000000000000006044820152606401610aee565b82815261012081018290526004546136d790836153cf565b6101408201526000602082015260115460405163ad0197db60e01b81526001600160a01b039091169063ad0197db90613714908490600401614f87565b600060405180830381600087803b15801561372e57600080fd5b505af1158015613742573d6000803e3d6000fd5b50506040518592507f257b6e0c207001c05b4f0f88a5bc913e2c47513ab9989881a48ceea263b2a7219150600090a2505050565b6137808282611e84565b15610e46576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60015460ff1661316f5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610aee565b60008082336001600160a01b0382161461386257600c546001600160a01b031633146138625760405162461bcd60e51b8152600401610aee9061570c565b60005b8551811015613ba85760115486516000916001600160a01b031690632d148d0a90899085908110613898576138986156a2565b60200260200101516040518263ffffffff1660e01b81526004016138be91815260200190565b61016060405180830381865afa1580156138dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613900919061553b565b60115488519192506000916001600160a01b0390911690630e6c893a908a908690811061392f5761392f6156a2565b6020026020010151896040518363ffffffff1660e01b81526004016139679291909182526001600160a01b0316602082015260400190565b606060405180830381865afa158015613984573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139a891906155d5565b90506002826020015160038111156139c2576139c2614f4f565b14613a0f5760405162461bcd60e51b815260206004820152601e60248201527f526f756e64206e6f7420656c696769626c6520666f72207265776172647300006044820152606401610aee565b6000826080015111613a5a5760405162461bcd60e51b8152602060048201526014602482015273139bc818995d1cc81a5b881d1a19481c9bdd5b9960621b6044820152606401610aee565b8161010001518260e0015103613abf57613a738261495b565b613abf5760405162461bcd60e51b815260206004820152601760248201527f4e6f7420656c696769626c6520666f7220726566756e640000000000000000006044820152606401610aee565b613ac98282611f87565b15613b9357600080613adb8484614811565b6001600160a01b038b16600090815260126020526040902054919350915060ff1615613b0d57613b0a8261498b565b91505b8351613b1b908a8484614a3a565b613b2582896153cf565b9750613b3181886153cf565b9650898581518110613b4557613b456156a2565b6020026020010151896001600160a01b03167f34fcbac0073d7c3d388e51312faf357774904998eeb8fca628b9e6f65ee1cbf784604051613b8891815260200190565b60405180910390a350505b50508080613ba0906156b8565b915050613865565b50509250929050565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613bfe576040519150601f19603f3d011682016040523d82523d6000602084013e613c03565b606091505b5050905080610ce95760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c4544006044820152606401610aee565b60115460405163168a468560e11b8152600481018490526000916001600160a01b031690632d148d0a9060240161016060405180830381865afa158015613c9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cc3919061553b565b905081600003613cd657610ce98361427b565b600081602001516003811115613cee57613cee614f4f565b14613d3b5760405162461bcd60e51b815260206004820152601760248201527f526f756e642073686f756c6420626520637265617465640000000000000000006044820152606401610aee565b428161012001511115613d905760405162461bcd60e51b815260206004820152601c60248201527f546f6f206561726c7920746f2073746172742074686520726f756e64000000006044820152606401610aee565b6011546040516352f3e91960e01b81526001600160a01b03909116906352f3e91990613dc790869060019087908290600401615780565b600060405180830381600087803b158015613de157600080fd5b505af1158015613df5573d6000803e3d6000fd5b50506040518592507f939f42374aa9bf1d8d8cd56d8a9110cb040cd8dfeae44080c6fcf2645e51b4529150600090a2505050565b60115460405163168a468560e11b8152600481018490526000916001600160a01b031690632d148d0a9060240161016060405180830381865afa158015613e74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e98919061553b565b9050600181602001516003811115613eb257613eb2614f4f565b14613eff5760405162461bcd60e51b815260206004820152601860248201527f526f756e64206973206e6f7420737461727465642079657400000000000000006044820152606401610aee565b428161014001511115613f545760405162461bcd60e51b815260206004820152601a60248201527f546f6f206561726c7920746f20656e642074686520726f756e640000000000006044820152606401610aee565b6011546040516352f3e91960e01b81526001600160a01b03909116906352f3e91990613f8c9086906002908790600090600401615780565b600060405180830381600087803b158015613fa657600080fd5b505af1158015613fba573d6000803e3d6000fd5b50506040518592507f2c46d8d5cabadbc3b7c8644a09e45c97988bd5ee29b298d282a7ef8c1833d9129150600090a2505050565b60115460405163168a468560e11b8152600481018390526000916001600160a01b031690632d148d0a9060240161016060405180830381865afa158015614039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061405d919061553b565b905060028160200151600381111561407757614077614f4f565b146140b95760405162461bcd60e51b8152602060048201526012602482015271149bdd5b99081a5cc81b9bdd08195b99195960721b6044820152606401610aee565b60006140c6826080015190565b90506000600b54600a6140d9919061588f565b60075484608001516140eb91906153e7565b6140f591906156d1565b905060008360e00151846101000151111561414957506040830151821580159061411e57508183115b156141305761412d8284615381565b92505b806000036141445783606001519150600092505b61419f565b8360e00151846101000151101561419857506060830151821580159061416e57508183115b156141805761417d8284615381565b92505b8060000361414457836040015191506000925061419f565b5060009150815b81600a60008282546141b191906153cf565b909155505060115460405163ddae3a7160e01b81526004810187905260248101859052604481018390526001600160a01b039091169063ddae3a7190606401600060405180830381600087803b15801561420a57600080fd5b505af115801561421e573d6000803e3d6000fd5b50505050614231828461352391906153cf565b604080518281526020810185905290810183905285907f6dfdfcb09c8804d0058826cd2539f1acfbe3cb887c9be03d928035bce0f1a58d9060600160405180910390a25050505050565b60115460405163168a468560e11b8152600481018390526000916001600160a01b031690632d148d0a9060240161016060405180830381865afa1580156142c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142ea919061553b565b905060038160200151600381111561430457614304614f4f565b0361435f5760405162461bcd60e51b815260206004820152602560248201527f43616e6e6f742063616e63656c20616c72656164792063616e63656c6c6564206044820152641c9bdd5b9960da1b6064820152608401610aee565b601154604051637e07ab0960e01b8152600481018490526001600160a01b0390911690637e07ab0990602401600060405180830381600087803b1580156143a557600080fd5b505af11580156143b9573d6000803e3d6000fd5b50506040518492507f1316afc2a7dc68d55247ceedbef28ffd97f61bafc159c949278f4b934d448c7b9150600090a25050565b6143f4613129565b6001805460ff1916811790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258335b6040516001600160a01b03909116815260200160405180910390a1565b81336001600160a01b0382161461447b57600c546001600160a01b0316331461447b5760405162461bcd60e51b8152600401610aee9061570c565b60115460405163168a468560e11b8152600481018690526000916001600160a01b031690632d148d0a9060240161016060405180830381865afa1580156144c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144ea919061553b565b90508061012001514211156145395760405162461bcd60e51b81526020600482015260156024820152741c9bdd5b9908185b1c9958591e481cdd185c9d1959605a1b6044820152606401610aee565b60008160200151600381111561455157614551614f4f565b14801561455e5750805115155b6145a25760405162461bcd60e51b815260206004820152601560248201527442657420697320746f6f206561726c792f6c61746560581b6044820152606401610aee565b6009548310156145c45760405162461bcd60e51b8152600401610aee90615734565b60115460405163ec4773a760e01b81526004810187905260248101859052600060448201526001600160a01b039091169063ec4773a790606401600060405180830381600087803b15801561461857600080fd5b505af115801561462c573d6000803e3d6000fd5b5050601154604051630736449d60e11b8152600481018990526001600160a01b038881166024830152600094509091169150630e6c893a90604401606060405180830381865afa158015614684573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146a891906155d5565b80519091501580156146bc57506020810151155b1561472857601154604051634a966a1b60e01b81526001600160a01b0387811660048301526024820189905290911690634a966a1b90604401600060405180830381600087803b15801561470f57600080fd5b505af1158015614723573d6000803e3d6000fd5b505050505b6011546040516331e1f08360e11b815260048101869052602481018890526001600160a01b03878116604483015260006064830152909116906363c3e10690608401600060405180830381600087803b15801561478457600080fd5b505af1158015614798573d6000803e3d6000fd5b5050505085856001600160a01b03167f546f54506a25044de11c4fb0c44fbd0137d87d7e08dfd800944453931428a5ea8660405161350991815260200190565b6147e06137db565b6001805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33614423565b6000808360e001518461010001510361487f5760208301518351600091614837916153cf565b90506148428561495b565b1561487957600b5461485590600a61588f565b60075461486290836153e7565b61486c91906156d1565b6148769082615381565b92505b506148f0565b8360e0015184610100015111156148b85750815160a084015160c08501516148a790836153e7565b6148b191906156d1565b91506148f0565b8360e0015184610100015110156148f05750602082015160a084015160c08501516148e390836153e7565b6148ed91906156d1565b91505b9250929050565b6149018282611e84565b610e4657614919816001600160a01b03166014614aad565b614924836020614aad565b6040516020016149359291906158cb565b60408051601f198184030181529082905262461bcd60e51b8252610aee91600401615940565b60008160a001516000148015614973575060c0820151155b8015610ac757505061010081015160e0909101511490565b600754819060009061499f906103e8615381565b6149ab846103e86153e7565b6149b591906156d1565b9050620186a060085460646149ca9190615381565b6007546149d790846153e7565b6149e191906153e7565b6149eb91906156d1565b6149f59082615381565b9150614a018383615381565b600a541115614a3057614a148383615381565b600a6000828254614a259190615381565b90915550614a349050565b8291505b50919050565b60115460405163720988c960e11b8152600481018690526001600160a01b038581166024830152604482018590529091169063e413119290606401600060405180830381600087803b158015614a8f57600080fd5b505af1158015614aa3573d6000803e3d6000fd5b5050505050505050565b60606000614abc8360026153e7565b614ac79060026153cf565b67ffffffffffffffff811115614adf57614adf614dc5565b6040519080825280601f01601f191660200182016040528015614b09576020820181803683370190505b509050600360fc1b81600081518110614b2457614b246156a2565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110614b5357614b536156a2565b60200101906001600160f81b031916908160001a9053506000614b778460026153e7565b614b829060016153cf565b90505b6001811115614bfa576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110614bb657614bb66156a2565b1a60f81b828281518110614bcc57614bcc6156a2565b60200101906001600160f81b031916908160001a90535060049490941c93614bf381615973565b9050614b85565b508315611a415760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610aee565b604051806101c001604052806000815260200160008152602001600081526020016000151581526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160006003811115614cb757614cb7614f4f565b815260006020820181905260409091015290565b600060208284031215614cdd57600080fd5b81356001600160e01b031981168114611a4157600080fd5b600060208284031215614d0757600080fd5b5035919050565b6001600160a01b038116811461352357600080fd5b8035614d2e81614d0e565b919050565b60008060408385031215614d4657600080fd5b823591506020830135614d5881614d0e565b809150509250929050565b600060208284031215614d7557600080fd5b8135611a4181614d0e565b60008083601f840112614d9257600080fd5b50813567ffffffffffffffff811115614daa57600080fd5b6020830191508360208260051b85010111156148f057600080fd5b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715614dfe57614dfe614dc5565b60405290565b604051610160810167ffffffffffffffff81118282101715614dfe57614dfe614dc5565b604051601f8201601f1916810167ffffffffffffffff81118282101715614e5157614e51614dc5565b604052919050565b60008060008084860360a0811215614e7057600080fd5b853567ffffffffffffffff811115614e8757600080fd5b614e9388828901614d80565b9096509450506020860135614ea781614d0e565b92506060603f1982011215614ebb57600080fd5b50614ec4614ddb565b604086013581526060860135602082015260808601358015158114614ee857600080fd5b6040820152939692955090935050565b600080600060408486031215614f0d57600080fd5b833567ffffffffffffffff811115614f2457600080fd5b614f3086828701614d80565b9094509250506020840135614f4481614d0e565b809150509250925092565b634e487b7160e01b600052602160045260246000fd5b60048110614f8357634e487b7160e01b600052602160045260246000fd5b9052565b81518152602080830151610160830191614fa390840182614f65565b5060408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e083015160e083015261010080840151818401525061012080840151818401525061014080840151818401525092915050565b6004811061352357600080fd5b8035614d2e8161500a565b60006060828403121561503457600080fd5b61503c614ddb565b905081358152602082013560208201526040820135604082015292915050565b6000808284036101c081121561507157600080fd5b6101608082121561508157600080fd5b615089614e04565b91508435825261509b60208601615017565b602083015260408501356040830152606085013560608301526080850135608083015260a085013560a083015260c085013560c083015260e085013560e083015261010080860135818401525061012080860135818401525061014080860135818401525081935061510f86828701615022565b925050509250929050565b60008060006060848603121561512f57600080fd5b833561513a81614d0e565b95602085013595506040909401359392505050565b6040808252835182820181905260009190606090818501906020808901865b838110156152265781518051865283810151848701528781015188870152868101511515878701526080808201519087015260a0808201519087015260c0808201519087015260e08082015190870152610100808201519087015261012080820151908701526101408082015190870152610160808201516151f282890182614f65565b505061018081810151908701526101a0908101516001600160a01b0316908601526101c0909401939082019060010161516e565b505095909501959095525092949350505050565b600067ffffffffffffffff82111561525457615254614dc5565b5060051b60200190565b6000806040838503121561527157600080fd5b823567ffffffffffffffff81111561528857600080fd5b8301601f8101851361529957600080fd5b803560206152ae6152a98361523a565b614e28565b82815260059290921b830181019181810190888411156152cd57600080fd5b938201935b838510156152eb578435825293820193908201906152d2565b95506152fa9050868201614d23565b93505050509250929050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60208082526014908201527320b2323932b9b9903737ba1030b71030b236b4b760611b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6000828210156153935761539361536b565b500390565b60208082526017908201527f41646472657373206e6f7420616e206f70657261746f72000000000000000000604082015260600190565b600082198211156153e2576153e261536b565b500190565b60008160001904831182151516156154015761540161536b565b500290565b6000602080838503121561541957600080fd5b825167ffffffffffffffff81111561543057600080fd5b8301601f8101851361544157600080fd5b805161544f6152a98261523a565b81815260059190911b8201830190838101908783111561546e57600080fd5b928401925b8284101561548c57835182529284019290840190615473565b979650505050505050565b60208082526034908201527f43616e206f6e6c792072756e20616674657220726f756e647a65726f437265616040820152731d19549bdd5b99081a5cc81d1c9a59d9d95c995960621b606082015260800190565b60208082526025908201527f43616e206f6e6c792072756e20726f756e647a65726f5374617274526f756e64604082015264206f6e636560d81b606082015260800190565b8051614d2e8161500a565b6000610160828403121561554e57600080fd5b615556614e04565b8251815261556660208401615530565b602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152506101208084015181830152506101408084015181830152508091505092915050565b6000606082840312156155e757600080fd5b6040516060810181811067ffffffffffffffff8211171561560a5761560a614dc5565b80604052508251815260208301516020820152604083015160408201528091505092915050565b6000806040838503121561564457600080fd5b82519150602083015160ff81168114614d5857600080fd5b60208082526026908201527f43616e206f6e6c792072756e20616674657220726f756e647a65726f537461726040820152651d149bdd5b9960d21b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b6000600182016156ca576156ca61536b565b5060010190565b6000826156ee57634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561570557600080fd5b5051919050565b6020808252600e908201526d24b73b30b634b21021b0b63632b960911b604082015260600190565b6020808252602c908201527f42657420616d6f756e74206d7573742062652067726561746572207468616e2060408201526b1b5a5b90995d105b5bdd5b9d60a21b606082015260800190565b848152608081016157946020830186614f65565b836040830152821515606083015295945050505050565b600181815b808511156157e65781600019048211156157cc576157cc61536b565b808516156157d957918102915b93841c93908002906157b0565b509250929050565b6000826157fd57506001610ac7565b8161580a57506000610ac7565b8160018114615820576002811461582a57615846565b6001915050610ac7565b60ff84111561583b5761583b61536b565b50506001821b610ac7565b5060208310610133831016604e8410600b8410161715615869575081810a610ac7565b61587383836157ab565b80600019048211156158875761588761536b565b029392505050565b6000611a4183836157ee565b60005b838110156158b657818101518382015260200161589e565b838111156158c5576000848401525b50505050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161590381601785016020880161589b565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161593481602884016020880161589b565b01602801949350505050565b602081526000825180602084015261595f81604085016020870161589b565b601f01601f19169190910160400192915050565b6000816159825761598261536b565b50600019019056fe97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929a26469706673582212202579c5f5399ff8a1cf2b785b87ade21d14616036a8183f5708f4be8209790de364736f6c634300080d00330000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000ab21ab51305043113213a963a373c771040c12510000000000000000000000001eb019e4ce27716e9405c3d8ba5819d23dbbf33100000000000000000000000074125975452b8ef51381dfef0a333d623a5df9200000000000000000000000008d868ff528cb3c64156826fb7d41c3b3b1da294e000000000000000000000000000000000000000000000000000000000000038442544300000000000000000000000000000000000000000000000000000000005553440000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106103545760003560e01c80638456cb59116101c6578063e0e081d7116100f7578063f4d508ec11610095578063f7b188a51161006f578063f7b188a514610a2b578063fa65cb0414610a40578063fb2f897a14610a60578063fc572b1814610a8057600080fd5b8063f4d508ec1461095f578063f5032980146109e9578063f5b541a614610a0957600080fd5b8063ec87621c116100d1578063ec87621c146108e0578063ee5f8c8f14610914578063efc3b2ea1461092a578063f2b3c8091461094a57600080fd5b8063e0e081d714610873578063e44bb72f146108ad578063e8712bd4146108c057600080fd5b8063a357a62011610164578063b6705a551161013e578063b6705a55146107fd578063bd9de03c1461081d578063cc32d1761461083d578063d547741f1461085357600080fd5b8063a357a6201461078f578063ac8a584a146107bd578063b3ab15fb146107dd57600080fd5b80639cbe5efd116101a05780639cbe5efd14610724578063a20037341461073a578063a217fddf1461075a578063a23e98841461076f57600080fd5b80638456cb59146106cd57806391d14854146106e25780639bb6eb701461070257600080fd5b8063445769cd116102a0578063733436201161023e578063783cf33211610218578063783cf33214610662578063795c29601461068257806379905dd5146106a25780637b3205f5146106b857600080fd5b8063733436201461060d57806377e0181f1461062d57806377e741c71461064257600080fd5b80635a9aa9571161027a5780635a9aa9571461058f5780635c975abb146105a5578063652b9b41146105bd5780636d27c9db146105ed57600080fd5b8063445769cd1461052f5780634b14c3d41461054f57806357957f691461056f57600080fd5b80632f2ff15d1161030d57806335538b69116102e757806335538b69146104b957806336568abe146104d9578063368acb09146104f957806340a201381461050f57600080fd5b80632f2ff15d1461044b578063313ce5671461046b578063325f700e1461048157600080fd5b806301ffc9a71461036057806309fffec01461039557806310082c75146103aa5780631c389c28146103da578063248a9ca3146103ed578063256b5a021461042b57600080fd5b3661035b57005b600080fd5b34801561036c57600080fd5b5061038061037b366004614ccb565b610a96565b60405190151581526020015b60405180910390f35b6103a86103a3366004614cf5565b610acd565b005b3480156103b657600080fd5b50600d54600e546103c5919082565b6040805192835260208301919091520161038c565b6103a86103e8366004614d33565b610bef565b3480156103f957600080fd5b5061041d610408366004614cf5565b60009081526020819052604090206001015490565b60405190815260200161038c565b34801561043757600080fd5b506103a8610446366004614d63565b610c30565b34801561045757600080fd5b506103a8610466366004614d33565b610cc4565b34801561047757600080fd5b5061041d600b5481565b34801561048d57600080fd5b50600f546104a1906001600160a01b031681565b6040516001600160a01b03909116815260200161038c565b3480156104c557600080fd5b506103a86104d4366004614cf5565b610cee565b3480156104e557600080fd5b506103a86104f4366004614d33565b610e4a565b34801561050557600080fd5b5061041d600a5481565b34801561051b57600080fd5b506103a861052a366004614d63565b610ec4565b34801561053b57600080fd5b506103a861054a366004614cf5565b610f0f565b34801561055b57600080fd5b506013546104a1906001600160a01b031681565b34801561057b57600080fd5b5061041d61058a366004614e59565b610fc4565b34801561059b57600080fd5b5061041d60055481565b3480156105b157600080fd5b5060015460ff16610380565b3480156105c957600080fd5b506103806105d8366004614d63565b60126020526000908152604090205460ff1681565b3480156105f957600080fd5b506103a8610608366004614cf5565b611153565b34801561061957600080fd5b506103a8610628366004614d33565b611249565b34801561063957600080fd5b506103a86114ed565b34801561064e57600080fd5b506103a861065d366004614cf5565b611659565b34801561066e57600080fd5b506103a861067d366004614cf5565b61171a565b34801561068e57600080fd5b5061041d61069d366004614ef8565b611950565b3480156106ae57600080fd5b5061041d60085481565b3480156106c457600080fd5b506103a8611a48565b3480156106d957600080fd5b506103a8611cd5565b3480156106ee57600080fd5b506103806106fd366004614d33565b611e84565b34801561070e57600080fd5b50610717611ead565b60405161038c9190614f87565b34801561073057600080fd5b5061041d60035481565b34801561074657600080fd5b5061038061075536600461505c565b611f87565b34801561076657600080fd5b5061041d600081565b34801561077b57600080fd5b506103a861078a366004614d63565b612002565b34801561079b57600080fd5b506107af6107aa36600461511a565b6120a4565b60405161038c92919061514f565b3480156107c957600080fd5b506103a86107d8366004614d63565b6126c5565b3480156107e957600080fd5b506103a86107f8366004614d63565b612705565b34801561080957600080fd5b506103a8610818366004614cf5565b6127cc565b34801561082957600080fd5b50600c546104a1906001600160a01b031681565b34801561084957600080fd5b5061041d60075481565b34801561085f57600080fd5b506103a861086e366004614d33565b612882565b34801561087f57600080fd5b506006546108969060ff8082169161010090041682565b60408051921515835290151560208301520161038c565b6103a86108bb366004614d33565b6128a7565b3480156108cc57600080fd5b506011546104a1906001600160a01b031681565b3480156108ec57600080fd5b5061041d7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b0881565b34801561092057600080fd5b5061041d60045481565b34801561093657600080fd5b506010546104a1906001600160a01b031681565b34801561095657600080fd5b5061041d606481565b34801561096b57600080fd5b5061097f61097a36600461511a565b6128df565b60405161038c929190600061012082019050835182526020840151602083015260408401516040830152606084015160608301526080840151608083015260a084015160a083015260c084015160c083015260e084015160e0830152826101008301529392505050565b3480156109f557600080fd5b506103a8610a04366004614d63565b612d0f565b348015610a1557600080fd5b5061041d60008051602061598b83398151915281565b348015610a3757600080fd5b506103a8612dcb565b348015610a4c57600080fd5b506103a8610a5b366004614cf5565b612ebf565b348015610a6c57600080fd5b5061041d610a7b36600461525e565b612f78565b348015610a8c57600080fd5b5061041d60095481565b60006001600160e01b03198216637965db0b60e01b1480610ac757506301ffc9a760e01b6001600160e01b03198316145b92915050565b6002805403610af75760405162461bcd60e51b8152600401610aee90615306565b60405180910390fd5b6002805533610b07600082611e84565b610b235760405162461bcd60e51b8152600401610aee9061533d565b600a54821115610b755760405162461bcd60e51b815260206004820152601c60248201527f5472616e7366657220616d6f756e7420697320746f6f206c61726765000000006044820152606401610aee565b81600a6000828254610b879190615381565b9091555050600f546001600160a01b0316610ba2818461311f565b806001600160a01b03167fc9262544ea8cacb7a3eea4ea7b4023ea10ac8bc73701610edba13308190f9cb184604051610bdd91815260200190565b60405180910390a25050600160025550565b610bf7613129565b6002805403610c185760405162461bcd60e51b8152600401610aee90615306565b60028055610c27828234613171565b50506001600255565b33610c3c600082611e84565b610c585760405162461bcd60e51b8152600401610aee9061533d565b6001600160a01b0382163b610c9f5760405162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081d985d5b1d609a1b6044820152606401610aee565b506001600160a01b03166000908152601260205260409020805460ff19166001179055565b600082815260208190526040902060010154610cdf81613519565b610ce98383613526565b505050565b610cf6613129565b33610d0f60008051602061598b83398151915282611e84565b610d2b5760405162461bcd60e51b8152600401610aee90615398565b600654610100900460ff1615610d925760405162461bcd60e51b815260206004820152602660248201527f43616e206f6e6c792072756e20726f756e647a65726f437265617465526f756e60448201526564206f6e636560d01b6064820152608401610aee565b600354610da09060016153cf565b60038190556005839055610db490836135aa565b6006805461ff001916610100179055600354610dea90610dd59060016153cf565b600454600554610de591906153cf565b6135aa565b610e176003546002610dfc91906153cf565b600454600554610e0d9082906153cf565b610de591906153cf565b610e466003546003610e2991906153cf565b6004546005548190610e3c9082906153cf565b610e0d91906153cf565b5050565b6001600160a01b0381163314610eba5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610aee565b610e468282613776565b33610ed0600082611e84565b610eec5760405162461bcd60e51b8152600401610aee9061533d565b50601380546001600160a01b0319166001600160a01b0392909216919091179055565b610f176137db565b33610f23600082611e84565b610f3f5760405162461bcd60e51b8152600401610aee9061533d565b60008211610f875760405162461bcd60e51b815260206004820152601560248201527404d757374206265207375706572696f7220746f203605c1b6044820152606401610aee565b60098290556040518281527f06a2e1014d8503fc3c899acda61fc50ab1918a70e8f904759a1f72f03bbd9cda906020015b60405180910390a15050565b60006002805403610fe75760405162461bcd60e51b8152600401610aee90615306565b60028055604080516020808702828101820190935286825261102692889188918291850190849080828437600092019190915250879250613824915050565b506040830151909150801561103b5750600081115b15611136576000604051806080016040528060008152602001600454600261106391906153e7565b61106d90426153cf565b8152644d4154494360d81b6020808301919091528581015160409283015260135486518351630c44410b60e41b815285516004820152928501516024840152928401516044830152606084015160648301526001600160a01b03888116608484015260a483019390935292935091169063c44410b090849060c40160006040518083038185885af1158015611106573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f1916820160405261112f9190810190615406565b5050611146565b8015611146576111468382613bb1565b6001600255949350505050565b61115b613129565b3361117460008051602061598b83398151915282611e84565b6111905760405162461bcd60e51b8152600401610aee90615398565b600654610100900460ff166111b75760405162461bcd60e51b8152600401610aee90615497565b60065460ff16156111da5760405162461bcd60e51b8152600401610aee906154eb565b60055442101561122c5760405162461bcd60e51b815260206004820152601d60248201527f526f756e642063616e6e6f742062652073746172746564206561726c790000006044820152606401610aee565b61123860035483613c54565b50506006805460ff19166001179055565b600280540361126a5760405162461bcd60e51b8152600401610aee90615306565b6002805560115460405163168a468560e11b8152600481018490526000916001600160a01b031690632d148d0a9060240161016060405180830381865afa1580156112b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112dd919061553b565b90506003816020015160038111156112f7576112f7614f4f565b146113445760405162461bcd60e51b815260206004820152601c60248201527f55736572206e6f7420656c696769626c6520666f7220726566756e64000000006044820152606401610aee565b601154604051630736449d60e11b8152600481018590526001600160a01b0384811660248301526000921690630e6c893a90604401606060405180830381865afa158015611396573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ba91906155d5565b905080604001516000146114095760405162461bcd60e51b81526020600482015260166024820152751499599d5b9908185b1c9958591e4818db185a5b595960521b6044820152606401610aee565b6020810151815160009161141c916153cf565b905080156114e15760115460405163720988c960e11b8152600481018790526001600160a01b038681166024830152604482018490529091169063e413119290606401600060405180830381600087803b15801561147957600080fd5b505af115801561148d573d6000803e3d6000fd5b5050505061149b8482613bb1565b604080518281524260208201526001600160a01b0386169187917faba4210cad11f1112f31ba136a61cdc0f6ab4c2b478da8c93eec1d9769e97a89910160405180910390a35b50506001600255505050565b6114f5613129565b3361150e60008051602061598b83398151915282611e84565b61152a5760405162461bcd60e51b8152600401610aee90615398565b600654610100900460ff166115515760405162461bcd60e51b8152600401610aee90615497565b60065460ff16156115745760405162461bcd60e51b8152600401610aee906154eb565b6005544210156115c65760405162461bcd60e51b815260206004820152601d60248201527f526f756e642063616e6e6f742062652073746172746564206561726c790000006044820152606401610aee565b601054600d54600e546005546040516319f59e5f60e01b81526004810193909352602483019190915260448201526000916001600160a01b0316906319f59e5f906064016040805180830381865afa158015611626573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164a9190615631565b50905061123860035482613c54565b6116616137db565b3361166d600082611e84565b6116895760405162461bcd60e51b8152600401610aee9061533d565b6000821180156116995750606482105b6116e55760405162461bcd60e51b815260206004820152601860248201527f54726561737572792066656520697320746f6f206869676800000000000000006044820152606401610aee565b60078290556040518281527f938d9272b26145999fe14f6124b73f122e1e023fc5de069c74ade1254408a97690602001610fb8565b611722613129565b3361173b60008051602061598b83398151915282611e84565b6117575760405162461bcd60e51b8152600401610aee90615398565b600654610100900460ff168015611770575060065460ff165b61178c5760405162461bcd60e51b8152600401610aee9061565c565b60115460035460405163168a468560e11b815260048101919091526000916001600160a01b031690632d148d0a9060240161016060405180830381865afa1580156117db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ff919061553b565b601154600380549293506000926001600160a01b0390921691632d148d0a9161182891906153cf565b6040518263ffffffff1660e01b815260040161184691815260200190565b61016060405180830381865afa158015611864573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611888919061553b565b90506003826020015160038111156118a2576118a2614f4f565b141580156118af57508315155b156118d0576118c060035485613e29565b6118cb600354613fee565b611904565b6003826020015160038111156118e8576118e8614f4f565b141580156118f4575083155b156119045761190460035461427b565b61191c600354600161191691906153cf565b85613c54565b611939600354600461192e91906153cf565b8261014001516135aa565b6003546119479060016153cf565b60035550505050565b6000805b83811015611a2d576011546000906001600160a01b0316630e6c893a878785818110611982576119826156a2565b90506020020135866040518363ffffffff1660e01b81526004016119b99291909182526001600160a01b0316602082015260400190565b606060405180830381865afa1580156119d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119fa91906155d5565b80516020820151919250611a0d916153cf565b611a1790846153cf565b9250508080611a25906156b8565b915050611954565b508215611a4157611a3e83826156d1565b90505b9392505050565b611a50613129565b600654610100900460ff168015611a69575060065460ff165b611a855760405162461bcd60e51b8152600401610aee9061565c565b60115460035460405163168a468560e11b815260048101919091526000916001600160a01b031690632d148d0a9060240161016060405180830381865afa158015611ad4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af8919061553b565b601154600380549293506000926001600160a01b0390921691632d148d0a91611b2191906153cf565b6040518263ffffffff1660e01b8152600401611b3f91815260200190565b61016060405180830381865afa158015611b5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b81919061553b565b601054600d54600e546101408601516040516319f59e5f60e01b81526004810193909352602483019190915260448201529192506000916001600160a01b03909116906319f59e5f906064016040805180830381865afa158015611be9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c0d9190615631565b509050600383602001516003811115611c2857611c28614f4f565b14158015611c3557508015155b15611c5657611c4660035482613e29565b611c51600354613fee565b611c8a565b600383602001516003811115611c6e57611c6e614f4f565b14158015611c7a575080155b15611c8a57611c8a60035461427b565b611ca26003546001611c9c91906153cf565b82613c54565b611cbf6003546004611cb491906153cf565b8361014001516135aa565b600354611ccd9060016153cf565b600355505050565b611cdd613129565b33611cf660008051602061598b83398151915282611e84565b611d125760405162461bcd60e51b8152600401610aee90615398565b611d1a6143ec565b6003545b601160009054906101000a90046001600160a01b03166001600160a01b03166311a8f4136040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9591906156f3565b8111611e455760115460405163168a468560e11b8152600481018390526000916001600160a01b031690632d148d0a9060240161016060405180830381865afa158015611de6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0a919061553b565b9050600381602001516003811115611e2457611e24614f4f565b14611e3257611e328261427b565b5080611e3d816156b8565b915050611d1e565b507fa382c86dbb1fba726013556ec174337b8f9ddac70b97ddb00d2e79e8b565d4f5600354604051611e7991815260200190565b60405180910390a150565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b611f0b6040805161016081019091526000808252602082019081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60115460035460405163168a468560e11b81526001600160a01b0390921691632d148d0a91611f409160040190815260200190565b61016060405180830381865afa158015611f5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f82919061553b565b905090565b8051600090151580611f9c5750602082015115155b8015611faa57506040820151155b8015611a4157508260e00151836101000151118015611fc95750815115155b80611fea57508260e00151836101000151108015611fea5750602082015115155b80611a415750505060e0810151610100909101511490565b3361200e600082611e84565b61202a5760405162461bcd60e51b8152600401610aee9061533d565b6001600160a01b0382163b6120815760405162461bcd60e51b815260206004820152601960248201527f4e6f7420426861766973682041646d696e6973747261746f72000000000000006044820152606401610aee565b50600f80546001600160a01b0319166001600160a01b0392909216919091179055565b601154604051630e9418a560e21b81526001600160a01b038581166004830152606092600092859284921690633a50629490602401600060405180830381865afa1580156120f6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261211e9190810190615406565b905085815161212d9190615381565b821115612144578581516121419190615381565b91505b60008267ffffffffffffffff81111561215f5761215f614dc5565b60405190808252806020026020018201604052801561219857816020015b612185614c49565b81526020019060019003908161217d5790505b50905060005b838110156126aa576011546000906001600160a01b0316630e6c893a856121c5858d6153cf565b815181106121d5576121d56156a2565b60200260200101518c6040518363ffffffff1660e01b815260040161220d9291909182526001600160a01b0316602082015260400190565b606060405180830381865afa15801561222a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224e91906155d5565b6011549091506000906001600160a01b0316632d148d0a86612270868e6153cf565b81518110612280576122806156a2565b60200260200101516040518263ffffffff1660e01b81526004016122a691815260200190565b61016060405180830381865afa1580156122c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122e8919061553b565b90508160000151848481518110612301576123016156a2565b602002602001015160000181815250508160200151848481518110612328576123286156a2565b60200260200101516020018181525050816000015184848151811061234f5761234f6156a2565b602090810291909101015152604082015161236b57600061236e565b60015b848481518110612380576123806156a2565b6020026020010151606001901515908115158152505080604001518484815181106123ad576123ad6156a2565b602002602001015160c001818152505080606001518484815181106123d4576123d46156a2565b602002602001015160e001818152505080600001518484815181106123fb576123fb6156a2565b602002602001015160a00181815250508060c00151848481518110612422576124226156a2565b60200260200101516101000181815250508060e0015184848151811061244a5761244a6156a2565b6020026020010151610120018181525050806101000151848481518110612473576124736156a2565b6020026020010151610140018181525050806020015184848151811061249b5761249b6156a2565b6020026020010151610160019060038111156124b9576124b9614f4f565b908160038111156124cc576124cc614f4f565b90525060408051600180825281830190925260009160208083019080368337019050509050856124fc858d6153cf565b8151811061250c5761250c6156a2565b602002602001015181600081518110612527576125276156a2565b602090810291909101015260028260200151600381111561254a5761254a614f4f565b148061256b575060038260200151600381111561256957612569614f4f565b145b156125b857600083604001511161258b57612586818d612f78565b612591565b82604001515b8585815181106125a3576125a36156a2565b602002602001015160400181815250506125dd565b60008585815181106125cc576125cc6156a2565b602002602001015160400181815250505b8161012001518585815181106125f5576125f56156a2565b6020026020010151608001818152505030858581518110612618576126186156a2565b60200260200101516101a001906001600160a01b031690816001600160a01b0316815250508160e001518261010001511161266b578160e001518261010001511061266457600261266e565b600161266e565b60005b60ff16858581518110612683576126836156a2565b602002602001015161018001818152505050505080806126a2906156b8565b91505061219e565b50806126b684896153cf565b94509450505050935093915050565b336126d1600082611e84565b6126ed5760405162461bcd60e51b8152600401610aee9061533d565b610e4660008051602061598b83398151915283612882565b33612711600082611e84565b61272d5760405162461bcd60e51b8152600401610aee9061533d565b6001600160a01b03821661277c5760405162461bcd60e51b815260206004820152601660248201527543616e6e6f74206265207a65726f206164647265737360501b6044820152606401610aee565b61279460008051602061598b83398151915283610cc4565b6040516001600160a01b038316907fda12ee837e6978172aaf54b16145ffe08414fd8710092ef033c71b8eb6ec189a90600090a25050565b6127d46137db565b336127e0600082611e84565b6127fc5760405162461bcd60e51b8152600401610aee9061533d565b606482111561284d5760405162461bcd60e51b815260206004820152601f60248201527f5661756c7420646973636f756e74207065726320697320746f6f2068696768006044820152606401610aee565b60088290556040518281527f1c3d6aca04a9d74c524b053538418e96eafc310c8d049c2a44f001d1b0c03fc390602001610fb8565b60008281526020819052604090206001015461289d81613519565b610ce98383613776565b6128af613129565b60028054036128d05760405162461bcd60e51b8152600401610aee90615306565b60028055610c27828234614440565b61292760405180610100016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b601154604051630e9418a560e21b81526001600160a01b0386811660048301526000928592849290911690633a50629490602401600060405180830381865afa158015612978573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526129a09190810190615406565b90508581516129af9190615381565b8211156129c6578581516129c39190615381565b91505b60005b82811015612cb0576011546000906001600160a01b0316630e6c893a846129f0858c6153cf565b81518110612a0057612a006156a2565b60200260200101518b6040518363ffffffff1660e01b8152600401612a389291909182526001600160a01b0316602082015260400190565b606060405180830381865afa158015612a55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a7991906155d5565b6011549091506000906001600160a01b0316632d148d0a85612a9b868d6153cf565b81518110612aab57612aab6156a2565b60200260200101516040518263ffffffff1660e01b8152600401612ad191815260200190565b61016060405180830381865afa158015612aef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b13919061553b565b9050600187604001818151612b2891906153cf565b90525060408051600180825281830190925260009160208083019080368337019050509050848481518110612b5f57612b5f6156a2565b602002602001015181600081518110612b7a57612b7a6156a2565b60200260200101818152505082602001518360000151612b9a91906153cf565b8860e001818151612bab91906153cf565b90525060e08201516101008301511115612c3f57825115612c1357600188600001818151612bd991906153cf565b9052506040830151612bf457612bef818c612f78565b612bfa565b82604001515b8860a001818151612c0b91906153cf565b905250612c9a565b600188602001818151612c2691906153cf565b905250602083015160c089018051612c0b9083906153cf565b8160e001518261010001511015612c9a57602083015115612c6d57600188600001818151612bd991906153cf565b600188602001818151612c8091906153cf565b905250825160c089018051612c969083906153cf565b9052505b5050508080612ca8906156b8565b9150506129c9565b50602084015184516040860151612cc79190615381565b612cd19190615381565b606085015260408401518451612cea90620186a06153e7565b612cf491906156d1565b6080850152612d0382876153cf565b92505050935093915050565b33612d1b600082611e84565b612d375760405162461bcd60e51b8152600401610aee9061533d565b6001600160a01b0382163b612d805760405162461bcd60e51b815260206004820152600f60248201526e696e76616c6964206164647265737360881b6044820152606401610aee565b600c80546001600160a01b0319166001600160a01b0384169081179091556040517f98902aabfcbed99d0d9769f20db2c97ad70f69f67ca8811518d37b9e590e0e8890600090a25050565b612dd36137db565b33612dec60008051602061598b83398151915282611e84565b612e085760405162461bcd60e51b8152600401610aee90615398565b6006805461ffff19169055601154604080516311a8f41360e01b815290516001600160a01b03909216916311a8f413916004808201926020929091908290030181865afa158015612e5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e8191906156f3565b600355612e8c6147d8565b7f0b0e422893e2219d69c6fba12911d3b270235e96e9753519998fc13013ebb2ae600354604051611e7991815260200190565b612ec76137db565b33612ee060008051602061598b83398151915282611e84565b612efc5760405162461bcd60e51b8152600401610aee90615398565b816000108015612f0f5750620151808211155b612f725760405162461bcd60e51b815260206004820152602e60248201527f526f756e642054696d652073686f756c64206265206265747765656e2031207360448201526d656320746f20333630302073656360901b6064820152608401610aee565b50600455565b600080805b84518110156131085760115485516000916001600160a01b031690632d148d0a90889085908110612fb057612fb06156a2565b60200260200101516040518263ffffffff1660e01b8152600401612fd691815260200190565b61016060405180830381865afa158015612ff4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613018919061553b565b60115487519192506000916001600160a01b0390911690630e6c893a90899086908110613047576130476156a2565b6020026020010151886040518363ffffffff1660e01b815260040161307f9291909182526001600160a01b0316602082015260400190565b606060405180830381865afa15801561309c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130c091906155d5565b90506130cc8282611f87565b6130d75750506130f6565b60006130e38383614811565b5090506130f081866153cf565b94505050505b80613100816156b8565b915050612f7d565b509392505050565b6001600160a01b03163b151590565b610e468282613bb1565b60015460ff161561316f5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610aee565b565b81336001600160a01b038216146131ac57600c546001600160a01b031633146131ac5760405162461bcd60e51b8152600401610aee9061570c565b60115460405163168a468560e11b8152600481018690526000916001600160a01b031690632d148d0a9060240161016060405180830381865afa1580156131f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061321b919061553b565b905060008160200151600381111561323557613235614f4f565b1480156132425750805115155b6132865760405162461bcd60e51b815260206004820152601560248201527442657420697320746f6f206561726c792f6c61746560581b6044820152606401610aee565b8061012001514211156132d35760405162461bcd60e51b81526020600482015260156024820152741c9bdd5b9908185b1c9958591e481cdd185c9d1959605a1b6044820152606401610aee565b6009548310156132f55760405162461bcd60e51b8152600401610aee90615734565b60115460405163ec4773a760e01b81526004810187905260248101859052600160448201526001600160a01b039091169063ec4773a790606401600060405180830381600087803b15801561334957600080fd5b505af115801561335d573d6000803e3d6000fd5b5050601154604051630736449d60e11b8152600481018990526001600160a01b038881166024830152600094509091169150630e6c893a90604401606060405180830381865afa1580156133b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133d991906155d5565b80519091501580156133ed57506020810151155b1561345957601154604051634a966a1b60e01b81526001600160a01b0387811660048301526024820189905290911690634a966a1b90604401600060405180830381600087803b15801561344057600080fd5b505af1158015613454573d6000803e3d6000fd5b505050505b6011546040516331e1f08360e11b815260048101869052602481018890526001600160a01b03878116604483015260016064830152909116906363c3e10690608401600060405180830381600087803b1580156134b557600080fd5b505af11580156134c9573d6000803e3d6000fd5b5050505085856001600160a01b03167f0bab430d5cfc26b856f9867d7019c5af92e6fb9f0eef60afadab9f0d53ff1fd38660405161350991815260200190565b60405180910390a3505050505050565b61352381336148f7565b50565b6135308282611e84565b610e46576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556135663390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60115460405163168a468560e11b8152600481018490526000916001600160a01b031690632d148d0a9060240161016060405180830381865afa1580156135f5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613619919061553b565b8051909150156136625760405162461bcd60e51b8152602060048201526014602482015273526f756e6420616c72656164792065786973747360601b6044820152606401610aee565b42600454836136719190615381565b10156136bf5760405162461bcd60e51b815260206004820152601760248201527f526f756e642074696d6520697320746f6f2073686f72740000000000000000006044820152606401610aee565b82815261012081018290526004546136d790836153cf565b6101408201526000602082015260115460405163ad0197db60e01b81526001600160a01b039091169063ad0197db90613714908490600401614f87565b600060405180830381600087803b15801561372e57600080fd5b505af1158015613742573d6000803e3d6000fd5b50506040518592507f257b6e0c207001c05b4f0f88a5bc913e2c47513ab9989881a48ceea263b2a7219150600090a2505050565b6137808282611e84565b15610e46576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60015460ff1661316f5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610aee565b60008082336001600160a01b0382161461386257600c546001600160a01b031633146138625760405162461bcd60e51b8152600401610aee9061570c565b60005b8551811015613ba85760115486516000916001600160a01b031690632d148d0a90899085908110613898576138986156a2565b60200260200101516040518263ffffffff1660e01b81526004016138be91815260200190565b61016060405180830381865afa1580156138dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613900919061553b565b60115488519192506000916001600160a01b0390911690630e6c893a908a908690811061392f5761392f6156a2565b6020026020010151896040518363ffffffff1660e01b81526004016139679291909182526001600160a01b0316602082015260400190565b606060405180830381865afa158015613984573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139a891906155d5565b90506002826020015160038111156139c2576139c2614f4f565b14613a0f5760405162461bcd60e51b815260206004820152601e60248201527f526f756e64206e6f7420656c696769626c6520666f72207265776172647300006044820152606401610aee565b6000826080015111613a5a5760405162461bcd60e51b8152602060048201526014602482015273139bc818995d1cc81a5b881d1a19481c9bdd5b9960621b6044820152606401610aee565b8161010001518260e0015103613abf57613a738261495b565b613abf5760405162461bcd60e51b815260206004820152601760248201527f4e6f7420656c696769626c6520666f7220726566756e640000000000000000006044820152606401610aee565b613ac98282611f87565b15613b9357600080613adb8484614811565b6001600160a01b038b16600090815260126020526040902054919350915060ff1615613b0d57613b0a8261498b565b91505b8351613b1b908a8484614a3a565b613b2582896153cf565b9750613b3181886153cf565b9650898581518110613b4557613b456156a2565b6020026020010151896001600160a01b03167f34fcbac0073d7c3d388e51312faf357774904998eeb8fca628b9e6f65ee1cbf784604051613b8891815260200190565b60405180910390a350505b50508080613ba0906156b8565b915050613865565b50509250929050565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613bfe576040519150601f19603f3d011682016040523d82523d6000602084013e613c03565b606091505b5050905080610ce95760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c4544006044820152606401610aee565b60115460405163168a468560e11b8152600481018490526000916001600160a01b031690632d148d0a9060240161016060405180830381865afa158015613c9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cc3919061553b565b905081600003613cd657610ce98361427b565b600081602001516003811115613cee57613cee614f4f565b14613d3b5760405162461bcd60e51b815260206004820152601760248201527f526f756e642073686f756c6420626520637265617465640000000000000000006044820152606401610aee565b428161012001511115613d905760405162461bcd60e51b815260206004820152601c60248201527f546f6f206561726c7920746f2073746172742074686520726f756e64000000006044820152606401610aee565b6011546040516352f3e91960e01b81526001600160a01b03909116906352f3e91990613dc790869060019087908290600401615780565b600060405180830381600087803b158015613de157600080fd5b505af1158015613df5573d6000803e3d6000fd5b50506040518592507f939f42374aa9bf1d8d8cd56d8a9110cb040cd8dfeae44080c6fcf2645e51b4529150600090a2505050565b60115460405163168a468560e11b8152600481018490526000916001600160a01b031690632d148d0a9060240161016060405180830381865afa158015613e74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e98919061553b565b9050600181602001516003811115613eb257613eb2614f4f565b14613eff5760405162461bcd60e51b815260206004820152601860248201527f526f756e64206973206e6f7420737461727465642079657400000000000000006044820152606401610aee565b428161014001511115613f545760405162461bcd60e51b815260206004820152601a60248201527f546f6f206561726c7920746f20656e642074686520726f756e640000000000006044820152606401610aee565b6011546040516352f3e91960e01b81526001600160a01b03909116906352f3e91990613f8c9086906002908790600090600401615780565b600060405180830381600087803b158015613fa657600080fd5b505af1158015613fba573d6000803e3d6000fd5b50506040518592507f2c46d8d5cabadbc3b7c8644a09e45c97988bd5ee29b298d282a7ef8c1833d9129150600090a2505050565b60115460405163168a468560e11b8152600481018390526000916001600160a01b031690632d148d0a9060240161016060405180830381865afa158015614039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061405d919061553b565b905060028160200151600381111561407757614077614f4f565b146140b95760405162461bcd60e51b8152602060048201526012602482015271149bdd5b99081a5cc81b9bdd08195b99195960721b6044820152606401610aee565b60006140c6826080015190565b90506000600b54600a6140d9919061588f565b60075484608001516140eb91906153e7565b6140f591906156d1565b905060008360e00151846101000151111561414957506040830151821580159061411e57508183115b156141305761412d8284615381565b92505b806000036141445783606001519150600092505b61419f565b8360e00151846101000151101561419857506060830151821580159061416e57508183115b156141805761417d8284615381565b92505b8060000361414457836040015191506000925061419f565b5060009150815b81600a60008282546141b191906153cf565b909155505060115460405163ddae3a7160e01b81526004810187905260248101859052604481018390526001600160a01b039091169063ddae3a7190606401600060405180830381600087803b15801561420a57600080fd5b505af115801561421e573d6000803e3d6000fd5b50505050614231828461352391906153cf565b604080518281526020810185905290810183905285907f6dfdfcb09c8804d0058826cd2539f1acfbe3cb887c9be03d928035bce0f1a58d9060600160405180910390a25050505050565b60115460405163168a468560e11b8152600481018390526000916001600160a01b031690632d148d0a9060240161016060405180830381865afa1580156142c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142ea919061553b565b905060038160200151600381111561430457614304614f4f565b0361435f5760405162461bcd60e51b815260206004820152602560248201527f43616e6e6f742063616e63656c20616c72656164792063616e63656c6c6564206044820152641c9bdd5b9960da1b6064820152608401610aee565b601154604051637e07ab0960e01b8152600481018490526001600160a01b0390911690637e07ab0990602401600060405180830381600087803b1580156143a557600080fd5b505af11580156143b9573d6000803e3d6000fd5b50506040518492507f1316afc2a7dc68d55247ceedbef28ffd97f61bafc159c949278f4b934d448c7b9150600090a25050565b6143f4613129565b6001805460ff1916811790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258335b6040516001600160a01b03909116815260200160405180910390a1565b81336001600160a01b0382161461447b57600c546001600160a01b0316331461447b5760405162461bcd60e51b8152600401610aee9061570c565b60115460405163168a468560e11b8152600481018690526000916001600160a01b031690632d148d0a9060240161016060405180830381865afa1580156144c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144ea919061553b565b90508061012001514211156145395760405162461bcd60e51b81526020600482015260156024820152741c9bdd5b9908185b1c9958591e481cdd185c9d1959605a1b6044820152606401610aee565b60008160200151600381111561455157614551614f4f565b14801561455e5750805115155b6145a25760405162461bcd60e51b815260206004820152601560248201527442657420697320746f6f206561726c792f6c61746560581b6044820152606401610aee565b6009548310156145c45760405162461bcd60e51b8152600401610aee90615734565b60115460405163ec4773a760e01b81526004810187905260248101859052600060448201526001600160a01b039091169063ec4773a790606401600060405180830381600087803b15801561461857600080fd5b505af115801561462c573d6000803e3d6000fd5b5050601154604051630736449d60e11b8152600481018990526001600160a01b038881166024830152600094509091169150630e6c893a90604401606060405180830381865afa158015614684573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146a891906155d5565b80519091501580156146bc57506020810151155b1561472857601154604051634a966a1b60e01b81526001600160a01b0387811660048301526024820189905290911690634a966a1b90604401600060405180830381600087803b15801561470f57600080fd5b505af1158015614723573d6000803e3d6000fd5b505050505b6011546040516331e1f08360e11b815260048101869052602481018890526001600160a01b03878116604483015260006064830152909116906363c3e10690608401600060405180830381600087803b15801561478457600080fd5b505af1158015614798573d6000803e3d6000fd5b5050505085856001600160a01b03167f546f54506a25044de11c4fb0c44fbd0137d87d7e08dfd800944453931428a5ea8660405161350991815260200190565b6147e06137db565b6001805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33614423565b6000808360e001518461010001510361487f5760208301518351600091614837916153cf565b90506148428561495b565b1561487957600b5461485590600a61588f565b60075461486290836153e7565b61486c91906156d1565b6148769082615381565b92505b506148f0565b8360e0015184610100015111156148b85750815160a084015160c08501516148a790836153e7565b6148b191906156d1565b91506148f0565b8360e0015184610100015110156148f05750602082015160a084015160c08501516148e390836153e7565b6148ed91906156d1565b91505b9250929050565b6149018282611e84565b610e4657614919816001600160a01b03166014614aad565b614924836020614aad565b6040516020016149359291906158cb565b60408051601f198184030181529082905262461bcd60e51b8252610aee91600401615940565b60008160a001516000148015614973575060c0820151155b8015610ac757505061010081015160e0909101511490565b600754819060009061499f906103e8615381565b6149ab846103e86153e7565b6149b591906156d1565b9050620186a060085460646149ca9190615381565b6007546149d790846153e7565b6149e191906153e7565b6149eb91906156d1565b6149f59082615381565b9150614a018383615381565b600a541115614a3057614a148383615381565b600a6000828254614a259190615381565b90915550614a349050565b8291505b50919050565b60115460405163720988c960e11b8152600481018690526001600160a01b038581166024830152604482018590529091169063e413119290606401600060405180830381600087803b158015614a8f57600080fd5b505af1158015614aa3573d6000803e3d6000fd5b5050505050505050565b60606000614abc8360026153e7565b614ac79060026153cf565b67ffffffffffffffff811115614adf57614adf614dc5565b6040519080825280601f01601f191660200182016040528015614b09576020820181803683370190505b509050600360fc1b81600081518110614b2457614b246156a2565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110614b5357614b536156a2565b60200101906001600160f81b031916908160001a9053506000614b778460026153e7565b614b829060016153cf565b90505b6001811115614bfa576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110614bb657614bb66156a2565b1a60f81b828281518110614bcc57614bcc6156a2565b60200101906001600160f81b031916908160001a90535060049490941c93614bf381615973565b9050614b85565b508315611a415760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610aee565b604051806101c001604052806000815260200160008152602001600081526020016000151581526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160006003811115614cb757614cb7614f4f565b815260006020820181905260409091015290565b600060208284031215614cdd57600080fd5b81356001600160e01b031981168114611a4157600080fd5b600060208284031215614d0757600080fd5b5035919050565b6001600160a01b038116811461352357600080fd5b8035614d2e81614d0e565b919050565b60008060408385031215614d4657600080fd5b823591506020830135614d5881614d0e565b809150509250929050565b600060208284031215614d7557600080fd5b8135611a4181614d0e565b60008083601f840112614d9257600080fd5b50813567ffffffffffffffff811115614daa57600080fd5b6020830191508360208260051b85010111156148f057600080fd5b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715614dfe57614dfe614dc5565b60405290565b604051610160810167ffffffffffffffff81118282101715614dfe57614dfe614dc5565b604051601f8201601f1916810167ffffffffffffffff81118282101715614e5157614e51614dc5565b604052919050565b60008060008084860360a0811215614e7057600080fd5b853567ffffffffffffffff811115614e8757600080fd5b614e9388828901614d80565b9096509450506020860135614ea781614d0e565b92506060603f1982011215614ebb57600080fd5b50614ec4614ddb565b604086013581526060860135602082015260808601358015158114614ee857600080fd5b6040820152939692955090935050565b600080600060408486031215614f0d57600080fd5b833567ffffffffffffffff811115614f2457600080fd5b614f3086828701614d80565b9094509250506020840135614f4481614d0e565b809150509250925092565b634e487b7160e01b600052602160045260246000fd5b60048110614f8357634e487b7160e01b600052602160045260246000fd5b9052565b81518152602080830151610160830191614fa390840182614f65565b5060408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e083015160e083015261010080840151818401525061012080840151818401525061014080840151818401525092915050565b6004811061352357600080fd5b8035614d2e8161500a565b60006060828403121561503457600080fd5b61503c614ddb565b905081358152602082013560208201526040820135604082015292915050565b6000808284036101c081121561507157600080fd5b6101608082121561508157600080fd5b615089614e04565b91508435825261509b60208601615017565b602083015260408501356040830152606085013560608301526080850135608083015260a085013560a083015260c085013560c083015260e085013560e083015261010080860135818401525061012080860135818401525061014080860135818401525081935061510f86828701615022565b925050509250929050565b60008060006060848603121561512f57600080fd5b833561513a81614d0e565b95602085013595506040909401359392505050565b6040808252835182820181905260009190606090818501906020808901865b838110156152265781518051865283810151848701528781015188870152868101511515878701526080808201519087015260a0808201519087015260c0808201519087015260e08082015190870152610100808201519087015261012080820151908701526101408082015190870152610160808201516151f282890182614f65565b505061018081810151908701526101a0908101516001600160a01b0316908601526101c0909401939082019060010161516e565b505095909501959095525092949350505050565b600067ffffffffffffffff82111561525457615254614dc5565b5060051b60200190565b6000806040838503121561527157600080fd5b823567ffffffffffffffff81111561528857600080fd5b8301601f8101851361529957600080fd5b803560206152ae6152a98361523a565b614e28565b82815260059290921b830181019181810190888411156152cd57600080fd5b938201935b838510156152eb578435825293820193908201906152d2565b95506152fa9050868201614d23565b93505050509250929050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60208082526014908201527320b2323932b9b9903737ba1030b71030b236b4b760611b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6000828210156153935761539361536b565b500390565b60208082526017908201527f41646472657373206e6f7420616e206f70657261746f72000000000000000000604082015260600190565b600082198211156153e2576153e261536b565b500190565b60008160001904831182151516156154015761540161536b565b500290565b6000602080838503121561541957600080fd5b825167ffffffffffffffff81111561543057600080fd5b8301601f8101851361544157600080fd5b805161544f6152a98261523a565b81815260059190911b8201830190838101908783111561546e57600080fd5b928401925b8284101561548c57835182529284019290840190615473565b979650505050505050565b60208082526034908201527f43616e206f6e6c792072756e20616674657220726f756e647a65726f437265616040820152731d19549bdd5b99081a5cc81d1c9a59d9d95c995960621b606082015260800190565b60208082526025908201527f43616e206f6e6c792072756e20726f756e647a65726f5374617274526f756e64604082015264206f6e636560d81b606082015260800190565b8051614d2e8161500a565b6000610160828403121561554e57600080fd5b615556614e04565b8251815261556660208401615530565b602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152506101208084015181830152506101408084015181830152508091505092915050565b6000606082840312156155e757600080fd5b6040516060810181811067ffffffffffffffff8211171561560a5761560a614dc5565b80604052508251815260208301516020820152604083015160408201528091505092915050565b6000806040838503121561564457600080fd5b82519150602083015160ff81168114614d5857600080fd5b60208082526026908201527f43616e206f6e6c792072756e20616674657220726f756e647a65726f537461726040820152651d149bdd5b9960d21b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b6000600182016156ca576156ca61536b565b5060010190565b6000826156ee57634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561570557600080fd5b5051919050565b6020808252600e908201526d24b73b30b634b21021b0b63632b960911b604082015260600190565b6020808252602c908201527f42657420616d6f756e74206d7573742062652067726561746572207468616e2060408201526b1b5a5b90995d105b5bdd5b9d60a21b606082015260800190565b848152608081016157946020830186614f65565b836040830152821515606083015295945050505050565b600181815b808511156157e65781600019048211156157cc576157cc61536b565b808516156157d957918102915b93841c93908002906157b0565b509250929050565b6000826157fd57506001610ac7565b8161580a57506000610ac7565b8160018114615820576002811461582a57615846565b6001915050610ac7565b60ff84111561583b5761583b61536b565b50506001821b610ac7565b5060208310610133831016604e8410600b8410161715615869575081810a610ac7565b61587383836157ab565b80600019048211156158875761588761536b565b029392505050565b6000611a4183836157ee565b60005b838110156158b657818101518382015260200161589e565b838111156158c5576000848401525b50505050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161590381601785016020880161589b565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161593481602884016020880161589b565b01602801949350505050565b602081526000825180602084015261595f81604085016020870161589b565b601f01601f19169190910160400192915050565b6000816159825761598261536b565b50600019019056fe97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929a26469706673582212202579c5f5399ff8a1cf2b785b87ade21d14616036a8183f5708f4be8209790de364736f6c634300080d0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000ab21ab51305043113213a963a373c771040c12510000000000000000000000001eb019e4ce27716e9405c3d8ba5819d23dbbf33100000000000000000000000074125975452b8ef51381dfef0a333d623a5df9200000000000000000000000008d868ff528cb3c64156826fb7d41c3b3b1da294e000000000000000000000000000000000000000000000000000000000000038442544300000000000000000000000000000000000000000000000000000000005553440000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _minPredictAmount (uint256): 1000000000000000000
Arg [1] : _treasuryFee (uint256): 40
Arg [2] : _bhavishAdmin (address): 0xaB21AB51305043113213a963a373c771040C1251
Arg [3] : _bhavishPriceManager (address): 0x1eB019E4cE27716e9405c3D8bA5819D23DbbF331
Arg [4] : _bhavishPredictionStorage (address): 0x74125975452B8eF51381dfEF0A333D623A5Df920
Arg [5] : _bhavishSwap (address): 0x8d868ff528CB3C64156826Fb7d41C3b3B1da294e
Arg [6] : _roundTime (uint256): 900
Arg [7] : _underlying (bytes32): 0x4254430000000000000000000000000000000000000000000000000000000000
Arg [8] : _strike (bytes32): 0x5553440000000000000000000000000000000000000000000000000000000000
-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000de0b6b3a7640000
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000028
Arg [2] : 000000000000000000000000ab21ab51305043113213a963a373c771040c1251
Arg [3] : 0000000000000000000000001eb019e4ce27716e9405c3d8ba5819d23dbbf331
Arg [4] : 00000000000000000000000074125975452b8ef51381dfef0a333d623a5df920
Arg [5] : 0000000000000000000000008d868ff528cb3c64156826fb7d41c3b3b1da294e
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000384
Arg [7] : 4254430000000000000000000000000000000000000000000000000000000000
Arg [8] : 5553440000000000000000000000000000000000000000000000000000000000
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.