Source Code
Overview
ETH Balance
ETH Value
$0.21 (@ $2,958.18/ETH)Latest 25 from a total of 484 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Multi Withdraw E... | 13588687 | 399 days ago | IN | 0 ETH | 0.00000205 | ||||
| Multi Withdraw E... | 4753270 | 612 days ago | IN | 0 ETH | 0.00000592 | ||||
| Multi Withdraw E... | 4753217 | 612 days ago | IN | 0 ETH | 0.00000592 | ||||
| Multi Withdraw E... | 4751478 | 612 days ago | IN | 0 ETH | 0.00000307 | ||||
| Multi Withdraw E... | 4749772 | 613 days ago | IN | 0 ETH | 0.00000247 | ||||
| Multi Withdraw E... | 4748344 | 613 days ago | IN | 0 ETH | 0.00000236 | ||||
| Multi Withdraw E... | 4747088 | 613 days ago | IN | 0 ETH | 0.00000239 | ||||
| Multi Withdraw E... | 4746705 | 613 days ago | IN | 0 ETH | 0.00000239 | ||||
| Multi Withdraw E... | 4743431 | 613 days ago | IN | 0 ETH | 0.0000023 | ||||
| Multi Withdraw E... | 4730960 | 613 days ago | IN | 0 ETH | 0.00000828 | ||||
| Multi Withdraw E... | 4730119 | 613 days ago | IN | 0 ETH | 0.0000038 | ||||
| Multi Withdraw E... | 4729791 | 613 days ago | IN | 0 ETH | 0.0000032 | ||||
| Multi Withdraw E... | 3931507 | 641 days ago | IN | 0 ETH | 0.00000225 | ||||
| Multi Withdraw E... | 3931329 | 641 days ago | IN | 0 ETH | 0.0000037 | ||||
| Multi Withdraw E... | 3926486 | 641 days ago | IN | 0 ETH | 0.00000255 | ||||
| Multi Withdraw E... | 3924997 | 641 days ago | IN | 0 ETH | 0.00000267 | ||||
| Multi Withdraw E... | 3923793 | 641 days ago | IN | 0 ETH | 0.0000029 | ||||
| Multi Withdraw E... | 3923456 | 641 days ago | IN | 0 ETH | 0.00000299 | ||||
| Multi Withdraw E... | 3923212 | 641 days ago | IN | 0 ETH | 0.00000303 | ||||
| Multi Withdraw E... | 3922961 | 641 days ago | IN | 0 ETH | 0.00000307 | ||||
| Multi Withdraw E... | 3922172 | 641 days ago | IN | 0 ETH | 0.00000333 | ||||
| Multi Withdraw E... | 3921372 | 641 days ago | IN | 0 ETH | 0.00000586 | ||||
| Multi Withdraw E... | 3921041 | 641 days ago | IN | 0 ETH | 0.00000359 | ||||
| Multi Withdraw E... | 3920946 | 641 days ago | IN | 0 ETH | 0.0000036 | ||||
| Multi Withdraw E... | 3920792 | 641 days ago | IN | 0 ETH | 0.0000036 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 13588687 | 399 days ago | 0.0001 ETH | ||||
| 13566781 | 399 days ago | 0.000075 ETH | ||||
| 4753270 | 612 days ago | 0.0001 ETH | ||||
| 4753217 | 612 days ago | 0.0001 ETH | ||||
| 4751478 | 612 days ago | 0.0001 ETH | ||||
| 4749772 | 613 days ago | 0.0001 ETH | ||||
| 4748344 | 613 days ago | 0.0001 ETH | ||||
| 4747088 | 613 days ago | 0.0001 ETH | ||||
| 4746705 | 613 days ago | 0.0001 ETH | ||||
| 4743431 | 613 days ago | 0.0001 ETH | ||||
| 4730960 | 613 days ago | 0.0001 ETH | ||||
| 4730119 | 613 days ago | 0.0001 ETH | ||||
| 4729791 | 613 days ago | 0.0001 ETH | ||||
| 4729008 | 613 days ago | 0.001125 ETH | ||||
| 3931507 | 641 days ago | 0.0001 ETH | ||||
| 3931329 | 641 days ago | 0.0001 ETH | ||||
| 3926486 | 641 days ago | 0.0001 ETH | ||||
| 3924997 | 641 days ago | 0.0001 ETH | ||||
| 3923793 | 641 days ago | 0.0001 ETH | ||||
| 3923456 | 641 days ago | 0.0001 ETH | ||||
| 3923212 | 641 days ago | 0.0001 ETH | ||||
| 3922961 | 641 days ago | 0.0001 ETH | ||||
| 3922172 | 641 days ago | 0.0001 ETH | ||||
| 3921372 | 641 days ago | 0.0001 ETH | ||||
| 3921041 | 641 days ago | 0.0001 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Manager
Compiler Version
v0.8.4+commit.c7e474f2
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
struct EthRecipient {
address to;
uint256 amount;
}
struct Erc20Recipient {
address token;
address to;
uint256 amount;
}
contract Manager is AccessControl {
using SafeERC20 for IERC20;
uint256 public ethPeriod; // native asset (eth) period
uint256 public ethPeriodicMaxCap; // native asset periodic cap
mapping(uint256 => uint256) public ethTotalWithdrawals; // period => amount
mapping(address => uint256) public erc20Periods; // erc20 token => period
mapping(address => uint256) public erc20PeriodicMaxCap; // erc20 token => erc20 periodic max cap
mapping(address => mapping(uint256 => uint256)) public erc20Withdrawals; // erc20 token => period => period withrawals
bytes32 public constant UNITAP_ROLE = keccak256("UNITAP_ROLE");
constructor(
uint256 period_,
uint256 periodicMaxCap_,
address admin,
address unitap
) {
require(
admin != address(0) && unitap != address(0),
"Manager: ZERO_ADDRESS"
);
ethPeriod = period_;
ethPeriodicMaxCap = periodicMaxCap_;
_setupRole(DEFAULT_ADMIN_ROLE, admin);
_setupRole(UNITAP_ROLE, unitap);
}
modifier onlyUnitapOrAdmin() {
require(
hasRole(UNITAP_ROLE, msg.sender) ||
hasRole(DEFAULT_ADMIN_ROLE, msg.sender),
"Manager: UNAUTHORIZED"
);
_;
}
function getActivePeriod(uint256 period_) public view returns (uint256) {
return (block.timestamp / period_) * period_;
}
function _checkAndUpdateEthMaxCap(uint256 amount) internal {
if (!hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) {
require(
ethTotalWithdrawals[getActivePeriod(ethPeriod)] + amount <=
ethPeriodicMaxCap,
"Manager: PERIODIC_MAX_CAP_EXCEEDED"
);
ethTotalWithdrawals[getActivePeriod(ethPeriod)] += amount;
}
}
function _checkAndUpdateErc20MaxCap(address token, uint256 amount)
internal
{
if (!hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) {
require(
erc20Withdrawals[token][getActivePeriod(erc20Periods[token])] +
amount <=
erc20PeriodicMaxCap[token],
"Manager: PERIODIC_MAX_CAP_EXCEEDED"
);
erc20Withdrawals[token][
getActivePeriod(erc20Periods[token])
] += amount;
}
}
function withdrawEth(uint256 amount, address to) public onlyUnitapOrAdmin {
// allow DEFALUT_ADMIN to withdraw as much as he wants
_checkAndUpdateEthMaxCap(amount);
payable(to).transfer(amount);
}
function multiWithdrawEth(EthRecipient[] memory recipients)
external
onlyRole(UNITAP_ROLE)
{
for (uint8 i = 0; i < recipients.length; i++)
withdrawEth(recipients[i].amount, recipients[i].to);
}
function withdrawErc20(
address token,
uint256 amount,
address to
) public onlyUnitapOrAdmin {
_checkAndUpdateErc20MaxCap(token, amount);
IERC20(token).safeTransfer(to, amount);
}
function multiWithdrawErc20(Erc20Recipient[] memory recipients)
external
onlyRole(UNITAP_ROLE)
{
for (uint8 i = 0; i < recipients.length; i++)
withdrawErc20(
recipients[i].token,
recipients[i].amount,
recipients[i].to
);
}
function setEthParams(uint256 period_, uint256 periodicMaxCap_)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
ethPeriod = period_;
ethPeriodicMaxCap = periodicMaxCap_;
}
function setErc20Params(
address token,
uint256 period_,
uint256 periodicMaxCap_
) external onlyRole(DEFAULT_ADMIN_ROLE) {
erc20Periods[token] = period_;
erc20PeriodicMaxCap[token] = periodicMaxCap_;
}
receive() external payable {}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.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(account),
" is missing role ",
Strings.toHexString(uint256(role), 32)
)
)
);
}
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleGranted} event.
*/
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleRevoked} event.
*/
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*
* May emit a {RoleRevoked} event.
*/
function renounceRole(bytes32 role, address account) public virtual override {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event. Note that unlike {grantRole}, this function doesn't perform any
* checks on the calling account.
*
* May emit a {RoleGranted} event.
*
* [WARNING]
* ====
* This function should only be called from the constructor when setting
* up the initial roles for the system.
*
* Using this function in any other way is effectively circumventing the admin
* system imposed by {AccessControl}.
* ====
*
* NOTE: This function is deprecated in favor of {_grantRole}.
*/
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Grants `role` to `account`.
*
* Internal function without access restriction.
*
* May emit a {RoleGranted} event.
*/
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
/**
* @dev Revokes `role` from `account`.
*
* Internal function without access restriction.
*
* May emit a {RoleRevoked} event.
*/
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
}// 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.8.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* The default value of {decimals} is 18. To select a different value for
* {decimals} you should overload it.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the value {ERC20} uses, unless this function is
* overridden;
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
* - the caller must have allowance for ``from``'s tokens of at least
* `amount`.
*/
function transferFrom(
address from,
address to,
uint256 amount
) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `amount` of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
*/
function _transfer(
address from,
address to,
uint256 amount
) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
// Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
// decrementing then incrementing.
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
unchecked {
// Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
// Overflow not possible: amount <= accountBalance <= totalSupply.
_totalSupply -= amount;
}
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `amount`.
*
* Does not update the allowance amount in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Might emit an {Approval} event.
*/
function _spendAllowance(
address owner,
address spender,
uint256 amount
) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/draft-IERC20Permit.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}// 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.8.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1);
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator,
Rounding rounding
) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10**64) {
value /= 10**64;
result += 64;
}
if (value >= 10**32) {
value /= 10**32;
result += 32;
}
if (value >= 10**16) {
value /= 10**16;
result += 16;
}
if (value >= 10**8) {
value /= 10**8;
result += 8;
}
if (value >= 10**4) {
value /= 10**4;
result += 4;
}
if (value >= 10**2) {
value /= 10**2;
result += 2;
}
if (value >= 10**1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)
pragma solidity ^0.8.0;
import "./math/Math.sol";
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract TestToken is ERC20 {
constructor() ERC20("TestToken", "TST") {
_mint(msg.sender, 1000 * 10**decimals());
}
}{
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"uint256","name":"period_","type":"uint256"},{"internalType":"uint256","name":"periodicMaxCap_","type":"uint256"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"address","name":"unitap","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNITAP_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"erc20PeriodicMaxCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"erc20Periods","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"erc20Withdrawals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ethPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ethPeriodicMaxCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"ethTotalWithdrawals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"period_","type":"uint256"}],"name":"getActivePeriod","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":"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":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Erc20Recipient[]","name":"recipients","type":"tuple[]"}],"name":"multiWithdrawErc20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct EthRecipient[]","name":"recipients","type":"tuple[]"}],"name":"multiWithdrawEth","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":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"period_","type":"uint256"},{"internalType":"uint256","name":"periodicMaxCap_","type":"uint256"}],"name":"setErc20Params","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"period_","type":"uint256"},{"internalType":"uint256","name":"periodicMaxCap_","type":"uint256"}],"name":"setEthParams","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":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawErc20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawEth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60806040523480156200001157600080fd5b5060405162002b5a38038062002b5a8339818101604052810190620000379190620002ea565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015620000a25750600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b620000e4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000db906200037d565b60405180910390fd5b8360018190555082600281905550620001076000801b836200014360201b60201c565b620001397fc45f5d8c4e0dd67196dabbc11e523116decf1539277d39eda24c612b7d699031826200014360201b60201c565b505050506200044b565b6200015582826200015960201b60201c565b5050565b6200016b82826200024a60201b60201c565b6200024657600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550620001eb620002b460201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600033905090565b600081519050620002cd8162000417565b92915050565b600081519050620002e48162000431565b92915050565b600080600080608085870312156200030157600080fd5b60006200031187828801620002d3565b94505060206200032487828801620002d3565b93505060406200033787828801620002bc565b92505060606200034a87828801620002bc565b91505092959194509250565b6000620003656015836200039f565b91506200037282620003ee565b602082019050919050565b60006020820190508181036000830152620003988162000356565b9050919050565b600082825260208201905092915050565b6000620003bd82620003c4565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b7f4d616e616765723a205a45524f5f414444524553530000000000000000000000600082015250565b6200042281620003b0565b81146200042e57600080fd5b50565b6200043c81620003e4565b81146200044857600080fd5b50565b6126ff806200045b6000396000f3fe60806040526004361061012e5760003560e01c806391d14854116100ab578063a3dcedc81161006f578063a3dcedc81461041f578063afb5cb671461045c578063b95e518914610485578063d547741f146104b0578063dd1edc03146104d9578063e650fe481461050257610135565b806391d148541461033c578063979e8d7914610379578063994948fd146103a2578063a158657c146103cb578063a217fddf146103f457610135565b806336568abe116100f257806336568abe146102455780633891cc0c1461026e5780634425fa49146102ab5780635e2dfaf9146102d45780636eb500051461031157610135565b806301ffc9a71461013a5780631362915114610177578063228c076c146101a2578063248a9ca3146101df5780632f2ff15d1461021c57610135565b3661013557005b600080fd5b34801561014657600080fd5b50610161600480360381019061015c9190611c28565b61053f565b60405161016e9190611f7e565b60405180910390f35b34801561018357600080fd5b5061018c6105b9565b60405161019991906120b6565b60405180910390f35b3480156101ae57600080fd5b506101c960048036038101906101c49190611c51565b6105bf565b6040516101d691906120b6565b60405180910390f35b3480156101eb57600080fd5b5061020660048036038101906102019190611bc3565b6105df565b6040516102139190611f99565b60405180910390f35b34801561022857600080fd5b50610243600480360381019061023e9190611bec565b6105fe565b005b34801561025157600080fd5b5061026c60048036038101906102679190611bec565b61061f565b005b34801561027a57600080fd5b5061029560048036038101906102909190611a3e565b6106a2565b6040516102a291906120b6565b60405180910390f35b3480156102b757600080fd5b506102d260048036038101906102cd9190611ac9565b6106c7565b005b3480156102e057600080fd5b506102fb60048036038101906102f69190611a15565b610762565b60405161030891906120b6565b60405180910390f35b34801561031d57600080fd5b5061032661077a565b60405161033391906120b6565b60405180910390f35b34801561034857600080fd5b50610363600480360381019061035e9190611bec565b610780565b6040516103709190611f7e565b60405180910390f35b34801561038557600080fd5b506103a0600480360381019061039b9190611b18565b6107ea565b005b3480156103ae57600080fd5b506103c960048036038101906103c49190611b59565b61091b565b005b3480156103d757600080fd5b506103f260048036038101906103ed9190611c7a565b610a04565b005b34801561040057600080fd5b50610409610ad5565b6040516104169190611f99565b60405180910390f35b34801561042b57600080fd5b5061044660048036038101906104419190611c51565b610adc565b60405161045391906120b6565b60405180910390f35b34801561046857600080fd5b50610483600480360381019061047e9190611a7a565b610af4565b005b34801561049157600080fd5b5061049a610bab565b6040516104a79190611f99565b60405180910390f35b3480156104bc57600080fd5b506104d760048036038101906104d29190611bec565b610bcf565b005b3480156104e557600080fd5b5061050060048036038101906104fb9190611cb6565b610bf0565b005b34801561050e57600080fd5b5061052960048036038101906105249190611a15565b610c10565b60405161053691906120b6565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806105b257506105b182610c28565b5b9050919050565b60025481565b60008182426105ce91906121e1565b6105d89190612212565b9050919050565b6000806000838152602001908152602001600020600101549050919050565b610607826105df565b61061081610c92565b61061a8383610ca6565b505050565b610627610d86565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161068b90612096565b60405180910390fd5b61069e8282610d8e565b5050565b6006602052816000526040600020602052806000526040600020600091509150505481565b6000801b6106d481610c92565b82600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050505050565b60046020528060005260406000206000915090505481565b60015481565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b7fc45f5d8c4e0dd67196dabbc11e523116decf1539277d39eda24c612b7d69903161081481610c92565b60005b82518160ff16101561091657610903838260ff1681518110610862577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015160000151848360ff16815181106108aa577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015160400151858460ff16815181106108f2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015160200151610af4565b808061090e90612385565b915050610817565b505050565b7fc45f5d8c4e0dd67196dabbc11e523116decf1539277d39eda24c612b7d69903161094581610c92565b60005b82518160ff1610156109ff576109ec838260ff1681518110610993577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015160200151848360ff16815181106109db577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015160000151610a04565b80806109f790612385565b915050610948565b505050565b610a2e7fc45f5d8c4e0dd67196dabbc11e523116decf1539277d39eda24c612b7d69903133610780565b80610a425750610a416000801b33610780565b5b610a81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7890612036565b60405180910390fd5b610a8a82610e6f565b8073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610ad0573d6000803e3d6000fd5b505050565b6000801b81565b60036020528060005260406000206000915090505481565b610b1e7fc45f5d8c4e0dd67196dabbc11e523116decf1539277d39eda24c612b7d69903133610780565b80610b325750610b316000801b33610780565b5b610b71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b6890612036565b60405180910390fd5b610b7b8383610f25565b610ba681838573ffffffffffffffffffffffffffffffffffffffff1661110d9092919063ffffffff16565b505050565b7fc45f5d8c4e0dd67196dabbc11e523116decf1539277d39eda24c612b7d69903181565b610bd8826105df565b610be181610c92565b610beb8383610d8e565b505050565b6000801b610bfd81610c92565b8260018190555081600281905550505050565b60056020528060005260406000206000915090505481565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b610ca381610c9e610d86565b611193565b50565b610cb08282610780565b610d8257600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550610d27610d86565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600033905090565b610d988282610780565b15610e6b57600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550610e10610d86565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b610e7c6000801b33610780565b610f22576002548160036000610e936001546105bf565b815260200190815260200160002054610eac919061218b565b1115610eed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee490611ff6565b60405180910390fd5b8060036000610efd6001546105bf565b81526020019081526020016000206000828254610f1a919061218b565b925050819055505b50565b610f326000801b33610780565b61110957600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000611000600460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546105bf565b815260200190815260200160002054611019919061218b565b111561105a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105190611ff6565b60405180910390fd5b80600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006110e4600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546105bf565b81526020019081526020016000206000828254611101919061218b565b925050819055505b5050565b61118e8363a9059cbb60e01b848460405160240161112c929190611f55565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611218565b505050565b61119d8282610780565b611214576111aa816112df565b6111b88360001c602061130c565b6040516020016111c9929190611f1b565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120b9190611fb4565b60405180910390fd5b5050565b600061127a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166116069092919063ffffffff16565b90506000815111156112da578080602001905181019061129a9190611b9a565b6112d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d090612076565b60405180910390fd5b5b505050565b60606113058273ffffffffffffffffffffffffffffffffffffffff16601460ff1661130c565b9050919050565b60606000600283600261131f9190612212565b611329919061218b565b67ffffffffffffffff811115611368577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561139a5781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106113f8577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611482577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600060018460026114c29190612212565b6114cc919061218b565b90505b60018111156115b8577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110611534577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b1a60f81b828281518110611571577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806115b19061232a565b90506114cf565b50600084146115fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115f390611fd6565b60405180910390fd5b8091505092915050565b6060611615848460008561161e565b90509392505050565b606082471015611663576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161165a90612016565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161168c9190611f04565b60006040518083038185875af1925050503d80600081146116c9576040519150601f19603f3d011682016040523d82523d6000602084013e6116ce565b606091505b50915091506116df878383876116eb565b92505050949350505050565b6060831561174e576000835114156117465761170685611761565b611745576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161173c90612056565b60405180910390fd5b5b829050611759565b6117588383611784565b5b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000825111156117975781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117cb9190611fb4565b60405180910390fd5b60006117e76117e2846120f6565b6120d1565b9050808382526020820190508285606086028201111561180657600080fd5b60005b85811015611836578161181c8882611954565b845260208401935060608301925050600181019050611809565b5050509392505050565b600061185361184e84612122565b6120d1565b9050808382526020820190508285604086028201111561187257600080fd5b60005b858110156118a2578161188888826119b4565b845260208401935060408301925050600181019050611875565b5050509392505050565b6000813590506118bb81612656565b92915050565b600082601f8301126118d257600080fd5b81356118e28482602086016117d4565b91505092915050565b600082601f8301126118fc57600080fd5b813561190c848260208601611840565b91505092915050565b6000815190506119248161266d565b92915050565b60008135905061193981612684565b92915050565b60008135905061194e8161269b565b92915050565b60006060828403121561196657600080fd5b61197060606120d1565b90506000611980848285016118ac565b6000830152506020611994848285016118ac565b60208301525060406119a884828501611a00565b60408301525092915050565b6000604082840312156119c657600080fd5b6119d060406120d1565b905060006119e0848285016118ac565b60008301525060206119f484828501611a00565b60208301525092915050565b600081359050611a0f816126b2565b92915050565b600060208284031215611a2757600080fd5b6000611a35848285016118ac565b91505092915050565b60008060408385031215611a5157600080fd5b6000611a5f858286016118ac565b9250506020611a7085828601611a00565b9150509250929050565b600080600060608486031215611a8f57600080fd5b6000611a9d868287016118ac565b9350506020611aae86828701611a00565b9250506040611abf868287016118ac565b9150509250925092565b600080600060608486031215611ade57600080fd5b6000611aec868287016118ac565b9350506020611afd86828701611a00565b9250506040611b0e86828701611a00565b9150509250925092565b600060208284031215611b2a57600080fd5b600082013567ffffffffffffffff811115611b4457600080fd5b611b50848285016118c1565b91505092915050565b600060208284031215611b6b57600080fd5b600082013567ffffffffffffffff811115611b8557600080fd5b611b91848285016118eb565b91505092915050565b600060208284031215611bac57600080fd5b6000611bba84828501611915565b91505092915050565b600060208284031215611bd557600080fd5b6000611be38482850161192a565b91505092915050565b60008060408385031215611bff57600080fd5b6000611c0d8582860161192a565b9250506020611c1e858286016118ac565b9150509250929050565b600060208284031215611c3a57600080fd5b6000611c488482850161193f565b91505092915050565b600060208284031215611c6357600080fd5b6000611c7184828501611a00565b91505092915050565b60008060408385031215611c8d57600080fd5b6000611c9b85828601611a00565b9250506020611cac858286016118ac565b9150509250929050565b60008060408385031215611cc957600080fd5b6000611cd785828601611a00565b9250506020611ce885828601611a00565b9150509250929050565b611cfb8161226c565b82525050565b611d0a8161227e565b82525050565b611d198161228a565b82525050565b6000611d2a8261214e565b611d348185612164565b9350611d448185602086016122f7565b80840191505092915050565b6000611d5b82612159565b611d65818561216f565b9350611d758185602086016122f7565b611d7e8161243c565b840191505092915050565b6000611d9482612159565b611d9e8185612180565b9350611dae8185602086016122f7565b80840191505092915050565b6000611dc760208361216f565b9150611dd28261244d565b602082019050919050565b6000611dea60228361216f565b9150611df582612476565b604082019050919050565b6000611e0d60268361216f565b9150611e18826124c5565b604082019050919050565b6000611e3060158361216f565b9150611e3b82612514565b602082019050919050565b6000611e53601d8361216f565b9150611e5e8261253d565b602082019050919050565b6000611e76601783612180565b9150611e8182612566565b601782019050919050565b6000611e99602a8361216f565b9150611ea48261258f565b604082019050919050565b6000611ebc601183612180565b9150611ec7826125de565b601182019050919050565b6000611edf602f8361216f565b9150611eea82612607565b604082019050919050565b611efe816122e0565b82525050565b6000611f108284611d1f565b915081905092915050565b6000611f2682611e69565b9150611f328285611d89565b9150611f3d82611eaf565b9150611f498284611d89565b91508190509392505050565b6000604082019050611f6a6000830185611cf2565b611f776020830184611ef5565b9392505050565b6000602082019050611f936000830184611d01565b92915050565b6000602082019050611fae6000830184611d10565b92915050565b60006020820190508181036000830152611fce8184611d50565b905092915050565b60006020820190508181036000830152611fef81611dba565b9050919050565b6000602082019050818103600083015261200f81611ddd565b9050919050565b6000602082019050818103600083015261202f81611e00565b9050919050565b6000602082019050818103600083015261204f81611e23565b9050919050565b6000602082019050818103600083015261206f81611e46565b9050919050565b6000602082019050818103600083015261208f81611e8c565b9050919050565b600060208201905081810360008301526120af81611ed2565b9050919050565b60006020820190506120cb6000830184611ef5565b92915050565b60006120db6120ec565b90506120e78282612354565b919050565b6000604051905090565b600067ffffffffffffffff8211156121115761211061240d565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561213d5761213c61240d565b5b602082029050602081019050919050565b600081519050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612196826122e0565b91506121a1836122e0565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156121d6576121d56123af565b5b828201905092915050565b60006121ec826122e0565b91506121f7836122e0565b925082612207576122066123de565b5b828204905092915050565b600061221d826122e0565b9150612228836122e0565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612261576122606123af565b5b828202905092915050565b6000612277826122c0565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60005b838110156123155780820151818401526020810190506122fa565b83811115612324576000848401525b50505050565b6000612335826122e0565b91506000821415612349576123486123af565b5b600182039050919050565b61235d8261243c565b810181811067ffffffffffffffff8211171561237c5761237b61240d565b5b80604052505050565b6000612390826122ea565b915060ff8214156123a4576123a36123af565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b7f4d616e616765723a20504552494f4449435f4d41585f4341505f45584345454460008201527f4544000000000000000000000000000000000000000000000000000000000000602082015250565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b7f4d616e616765723a20554e415554484f52495a45440000000000000000000000600082015250565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b61265f8161226c565b811461266a57600080fd5b50565b6126768161227e565b811461268157600080fd5b50565b61268d8161228a565b811461269857600080fd5b50565b6126a481612294565b81146126af57600080fd5b50565b6126bb816122e0565b81146126c657600080fd5b5056fea264697066735822122026a894b3106162d687782045e5508768d567c2e3fa235a9da293aef0d6ed5e1264736f6c6343000804003300000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000b10f8e218a9cd738b0f1e2f7169aa3c0897f2d83000000000000000000000000b10f8e218a9cd738b0f1e2f7169aa3c0897f2d83
Deployed Bytecode
0x60806040526004361061012e5760003560e01c806391d14854116100ab578063a3dcedc81161006f578063a3dcedc81461041f578063afb5cb671461045c578063b95e518914610485578063d547741f146104b0578063dd1edc03146104d9578063e650fe481461050257610135565b806391d148541461033c578063979e8d7914610379578063994948fd146103a2578063a158657c146103cb578063a217fddf146103f457610135565b806336568abe116100f257806336568abe146102455780633891cc0c1461026e5780634425fa49146102ab5780635e2dfaf9146102d45780636eb500051461031157610135565b806301ffc9a71461013a5780631362915114610177578063228c076c146101a2578063248a9ca3146101df5780632f2ff15d1461021c57610135565b3661013557005b600080fd5b34801561014657600080fd5b50610161600480360381019061015c9190611c28565b61053f565b60405161016e9190611f7e565b60405180910390f35b34801561018357600080fd5b5061018c6105b9565b60405161019991906120b6565b60405180910390f35b3480156101ae57600080fd5b506101c960048036038101906101c49190611c51565b6105bf565b6040516101d691906120b6565b60405180910390f35b3480156101eb57600080fd5b5061020660048036038101906102019190611bc3565b6105df565b6040516102139190611f99565b60405180910390f35b34801561022857600080fd5b50610243600480360381019061023e9190611bec565b6105fe565b005b34801561025157600080fd5b5061026c60048036038101906102679190611bec565b61061f565b005b34801561027a57600080fd5b5061029560048036038101906102909190611a3e565b6106a2565b6040516102a291906120b6565b60405180910390f35b3480156102b757600080fd5b506102d260048036038101906102cd9190611ac9565b6106c7565b005b3480156102e057600080fd5b506102fb60048036038101906102f69190611a15565b610762565b60405161030891906120b6565b60405180910390f35b34801561031d57600080fd5b5061032661077a565b60405161033391906120b6565b60405180910390f35b34801561034857600080fd5b50610363600480360381019061035e9190611bec565b610780565b6040516103709190611f7e565b60405180910390f35b34801561038557600080fd5b506103a0600480360381019061039b9190611b18565b6107ea565b005b3480156103ae57600080fd5b506103c960048036038101906103c49190611b59565b61091b565b005b3480156103d757600080fd5b506103f260048036038101906103ed9190611c7a565b610a04565b005b34801561040057600080fd5b50610409610ad5565b6040516104169190611f99565b60405180910390f35b34801561042b57600080fd5b5061044660048036038101906104419190611c51565b610adc565b60405161045391906120b6565b60405180910390f35b34801561046857600080fd5b50610483600480360381019061047e9190611a7a565b610af4565b005b34801561049157600080fd5b5061049a610bab565b6040516104a79190611f99565b60405180910390f35b3480156104bc57600080fd5b506104d760048036038101906104d29190611bec565b610bcf565b005b3480156104e557600080fd5b5061050060048036038101906104fb9190611cb6565b610bf0565b005b34801561050e57600080fd5b5061052960048036038101906105249190611a15565b610c10565b60405161053691906120b6565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806105b257506105b182610c28565b5b9050919050565b60025481565b60008182426105ce91906121e1565b6105d89190612212565b9050919050565b6000806000838152602001908152602001600020600101549050919050565b610607826105df565b61061081610c92565b61061a8383610ca6565b505050565b610627610d86565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161068b90612096565b60405180910390fd5b61069e8282610d8e565b5050565b6006602052816000526040600020602052806000526040600020600091509150505481565b6000801b6106d481610c92565b82600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050505050565b60046020528060005260406000206000915090505481565b60015481565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b7fc45f5d8c4e0dd67196dabbc11e523116decf1539277d39eda24c612b7d69903161081481610c92565b60005b82518160ff16101561091657610903838260ff1681518110610862577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015160000151848360ff16815181106108aa577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015160400151858460ff16815181106108f2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015160200151610af4565b808061090e90612385565b915050610817565b505050565b7fc45f5d8c4e0dd67196dabbc11e523116decf1539277d39eda24c612b7d69903161094581610c92565b60005b82518160ff1610156109ff576109ec838260ff1681518110610993577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015160200151848360ff16815181106109db577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015160000151610a04565b80806109f790612385565b915050610948565b505050565b610a2e7fc45f5d8c4e0dd67196dabbc11e523116decf1539277d39eda24c612b7d69903133610780565b80610a425750610a416000801b33610780565b5b610a81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7890612036565b60405180910390fd5b610a8a82610e6f565b8073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610ad0573d6000803e3d6000fd5b505050565b6000801b81565b60036020528060005260406000206000915090505481565b610b1e7fc45f5d8c4e0dd67196dabbc11e523116decf1539277d39eda24c612b7d69903133610780565b80610b325750610b316000801b33610780565b5b610b71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b6890612036565b60405180910390fd5b610b7b8383610f25565b610ba681838573ffffffffffffffffffffffffffffffffffffffff1661110d9092919063ffffffff16565b505050565b7fc45f5d8c4e0dd67196dabbc11e523116decf1539277d39eda24c612b7d69903181565b610bd8826105df565b610be181610c92565b610beb8383610d8e565b505050565b6000801b610bfd81610c92565b8260018190555081600281905550505050565b60056020528060005260406000206000915090505481565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b610ca381610c9e610d86565b611193565b50565b610cb08282610780565b610d8257600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550610d27610d86565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600033905090565b610d988282610780565b15610e6b57600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550610e10610d86565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b610e7c6000801b33610780565b610f22576002548160036000610e936001546105bf565b815260200190815260200160002054610eac919061218b565b1115610eed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee490611ff6565b60405180910390fd5b8060036000610efd6001546105bf565b81526020019081526020016000206000828254610f1a919061218b565b925050819055505b50565b610f326000801b33610780565b61110957600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000611000600460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546105bf565b815260200190815260200160002054611019919061218b565b111561105a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105190611ff6565b60405180910390fd5b80600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006110e4600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546105bf565b81526020019081526020016000206000828254611101919061218b565b925050819055505b5050565b61118e8363a9059cbb60e01b848460405160240161112c929190611f55565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611218565b505050565b61119d8282610780565b611214576111aa816112df565b6111b88360001c602061130c565b6040516020016111c9929190611f1b565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120b9190611fb4565b60405180910390fd5b5050565b600061127a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166116069092919063ffffffff16565b90506000815111156112da578080602001905181019061129a9190611b9a565b6112d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d090612076565b60405180910390fd5b5b505050565b60606113058273ffffffffffffffffffffffffffffffffffffffff16601460ff1661130c565b9050919050565b60606000600283600261131f9190612212565b611329919061218b565b67ffffffffffffffff811115611368577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561139a5781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106113f8577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611482577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600060018460026114c29190612212565b6114cc919061218b565b90505b60018111156115b8577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110611534577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b1a60f81b828281518110611571577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806115b19061232a565b90506114cf565b50600084146115fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115f390611fd6565b60405180910390fd5b8091505092915050565b6060611615848460008561161e565b90509392505050565b606082471015611663576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161165a90612016565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161168c9190611f04565b60006040518083038185875af1925050503d80600081146116c9576040519150601f19603f3d011682016040523d82523d6000602084013e6116ce565b606091505b50915091506116df878383876116eb565b92505050949350505050565b6060831561174e576000835114156117465761170685611761565b611745576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161173c90612056565b60405180910390fd5b5b829050611759565b6117588383611784565b5b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000825111156117975781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117cb9190611fb4565b60405180910390fd5b60006117e76117e2846120f6565b6120d1565b9050808382526020820190508285606086028201111561180657600080fd5b60005b85811015611836578161181c8882611954565b845260208401935060608301925050600181019050611809565b5050509392505050565b600061185361184e84612122565b6120d1565b9050808382526020820190508285604086028201111561187257600080fd5b60005b858110156118a2578161188888826119b4565b845260208401935060408301925050600181019050611875565b5050509392505050565b6000813590506118bb81612656565b92915050565b600082601f8301126118d257600080fd5b81356118e28482602086016117d4565b91505092915050565b600082601f8301126118fc57600080fd5b813561190c848260208601611840565b91505092915050565b6000815190506119248161266d565b92915050565b60008135905061193981612684565b92915050565b60008135905061194e8161269b565b92915050565b60006060828403121561196657600080fd5b61197060606120d1565b90506000611980848285016118ac565b6000830152506020611994848285016118ac565b60208301525060406119a884828501611a00565b60408301525092915050565b6000604082840312156119c657600080fd5b6119d060406120d1565b905060006119e0848285016118ac565b60008301525060206119f484828501611a00565b60208301525092915050565b600081359050611a0f816126b2565b92915050565b600060208284031215611a2757600080fd5b6000611a35848285016118ac565b91505092915050565b60008060408385031215611a5157600080fd5b6000611a5f858286016118ac565b9250506020611a7085828601611a00565b9150509250929050565b600080600060608486031215611a8f57600080fd5b6000611a9d868287016118ac565b9350506020611aae86828701611a00565b9250506040611abf868287016118ac565b9150509250925092565b600080600060608486031215611ade57600080fd5b6000611aec868287016118ac565b9350506020611afd86828701611a00565b9250506040611b0e86828701611a00565b9150509250925092565b600060208284031215611b2a57600080fd5b600082013567ffffffffffffffff811115611b4457600080fd5b611b50848285016118c1565b91505092915050565b600060208284031215611b6b57600080fd5b600082013567ffffffffffffffff811115611b8557600080fd5b611b91848285016118eb565b91505092915050565b600060208284031215611bac57600080fd5b6000611bba84828501611915565b91505092915050565b600060208284031215611bd557600080fd5b6000611be38482850161192a565b91505092915050565b60008060408385031215611bff57600080fd5b6000611c0d8582860161192a565b9250506020611c1e858286016118ac565b9150509250929050565b600060208284031215611c3a57600080fd5b6000611c488482850161193f565b91505092915050565b600060208284031215611c6357600080fd5b6000611c7184828501611a00565b91505092915050565b60008060408385031215611c8d57600080fd5b6000611c9b85828601611a00565b9250506020611cac858286016118ac565b9150509250929050565b60008060408385031215611cc957600080fd5b6000611cd785828601611a00565b9250506020611ce885828601611a00565b9150509250929050565b611cfb8161226c565b82525050565b611d0a8161227e565b82525050565b611d198161228a565b82525050565b6000611d2a8261214e565b611d348185612164565b9350611d448185602086016122f7565b80840191505092915050565b6000611d5b82612159565b611d65818561216f565b9350611d758185602086016122f7565b611d7e8161243c565b840191505092915050565b6000611d9482612159565b611d9e8185612180565b9350611dae8185602086016122f7565b80840191505092915050565b6000611dc760208361216f565b9150611dd28261244d565b602082019050919050565b6000611dea60228361216f565b9150611df582612476565b604082019050919050565b6000611e0d60268361216f565b9150611e18826124c5565b604082019050919050565b6000611e3060158361216f565b9150611e3b82612514565b602082019050919050565b6000611e53601d8361216f565b9150611e5e8261253d565b602082019050919050565b6000611e76601783612180565b9150611e8182612566565b601782019050919050565b6000611e99602a8361216f565b9150611ea48261258f565b604082019050919050565b6000611ebc601183612180565b9150611ec7826125de565b601182019050919050565b6000611edf602f8361216f565b9150611eea82612607565b604082019050919050565b611efe816122e0565b82525050565b6000611f108284611d1f565b915081905092915050565b6000611f2682611e69565b9150611f328285611d89565b9150611f3d82611eaf565b9150611f498284611d89565b91508190509392505050565b6000604082019050611f6a6000830185611cf2565b611f776020830184611ef5565b9392505050565b6000602082019050611f936000830184611d01565b92915050565b6000602082019050611fae6000830184611d10565b92915050565b60006020820190508181036000830152611fce8184611d50565b905092915050565b60006020820190508181036000830152611fef81611dba565b9050919050565b6000602082019050818103600083015261200f81611ddd565b9050919050565b6000602082019050818103600083015261202f81611e00565b9050919050565b6000602082019050818103600083015261204f81611e23565b9050919050565b6000602082019050818103600083015261206f81611e46565b9050919050565b6000602082019050818103600083015261208f81611e8c565b9050919050565b600060208201905081810360008301526120af81611ed2565b9050919050565b60006020820190506120cb6000830184611ef5565b92915050565b60006120db6120ec565b90506120e78282612354565b919050565b6000604051905090565b600067ffffffffffffffff8211156121115761211061240d565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561213d5761213c61240d565b5b602082029050602081019050919050565b600081519050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612196826122e0565b91506121a1836122e0565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156121d6576121d56123af565b5b828201905092915050565b60006121ec826122e0565b91506121f7836122e0565b925082612207576122066123de565b5b828204905092915050565b600061221d826122e0565b9150612228836122e0565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612261576122606123af565b5b828202905092915050565b6000612277826122c0565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60005b838110156123155780820151818401526020810190506122fa565b83811115612324576000848401525b50505050565b6000612335826122e0565b91506000821415612349576123486123af565b5b600182039050919050565b61235d8261243c565b810181811067ffffffffffffffff8211171561237c5761237b61240d565b5b80604052505050565b6000612390826122ea565b915060ff8214156123a4576123a36123af565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b7f4d616e616765723a20504552494f4449435f4d41585f4341505f45584345454460008201527f4544000000000000000000000000000000000000000000000000000000000000602082015250565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b7f4d616e616765723a20554e415554484f52495a45440000000000000000000000600082015250565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b61265f8161226c565b811461266a57600080fd5b50565b6126768161227e565b811461268157600080fd5b50565b61268d8161228a565b811461269857600080fd5b50565b6126a481612294565b81146126af57600080fd5b50565b6126bb816122e0565b81146126c657600080fd5b5056fea264697066735822122026a894b3106162d687782045e5508768d567c2e3fa235a9da293aef0d6ed5e1264736f6c63430008040033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000b10f8e218a9cd738b0f1e2f7169aa3c0897f2d83000000000000000000000000b10f8e218a9cd738b0f1e2f7169aa3c0897f2d83
-----Decoded View---------------
Arg [0] : period_ (uint256): 86400
Arg [1] : periodicMaxCap_ (uint256): 1000000000000000000
Arg [2] : admin (address): 0xB10f8E218A9cD738b0F1E2f7169Aa3c0897F2d83
Arg [3] : unitap (address): 0xB10f8E218A9cD738b0F1E2f7169Aa3c0897F2d83
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000015180
Arg [1] : 0000000000000000000000000000000000000000000000000de0b6b3a7640000
Arg [2] : 000000000000000000000000b10f8e218a9cd738b0f1e2f7169aa3c0897f2d83
Arg [3] : 000000000000000000000000b10f8e218a9cd738b0f1e2f7169aa3c0897f2d83
Deployed Bytecode Sourcemap
326:3907:13:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2606:202:0;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;458:32:13;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1619:133;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4378:129:0;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4803:145;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;5912:214;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;786:71:13;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3947:249;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;606:47;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;399:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2895:145:0;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3406:326:13;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2930:237;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2700:224;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2027:49:0;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;525:54:13;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3173:227;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;909:62;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5228:147:0;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3738:203:13;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;684:54;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2606:202:0;2691:4;2729:32;2714:47;;;:11;:47;;;;:87;;;;2765:36;2789:11;2765:23;:36::i;:::-;2714:87;2707:94;;2606:202;;;:::o;458:32:13:-;;;;:::o;1619:133::-;1682:7;1738;1727;1709:15;:25;;;;:::i;:::-;1708:37;;;;:::i;:::-;1701:44;;1619:133;;;:::o;4378:129:0:-;4452:7;4478:6;:12;4485:4;4478:12;;;;;;;;;;;:22;;;4471:29;;4378:129;;;:::o;4803:145::-;4886:18;4899:4;4886:12;:18::i;:::-;2505:16;2516:4;2505:10;:16::i;:::-;4916:25:::1;4927:4;4933:7;4916:10;:25::i;:::-;4803:145:::0;;;:::o;5912:214::-;6018:12;:10;:12::i;:::-;6007:23;;:7;:23;;;5999:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;6093:26;6105:4;6111:7;6093:11;:26::i;:::-;5912:214;;:::o;786:71:13:-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;3947:249::-;2072:4:0;4076:18:13;;2505:16:0;2516:4;2505:10;:16::i;:::-;4128:7:13::1;4106:12;:19;4119:5;4106:19;;;;;;;;;;;;;;;:29;;;;4174:15;4145:19;:26;4165:5;4145:26;;;;;;;;;;;;;;;:44;;;;3947:249:::0;;;;:::o;606:47::-;;;;;;;;;;;;;;;;;:::o;399:24::-;;;;:::o;2895:145:0:-;2981:4;3004:6;:12;3011:4;3004:12;;;;;;;;;;;:20;;:29;3025:7;3004:29;;;;;;;;;;;;;;;;;;;;;;;;;2997:36;;2895:145;;;;:::o;3406:326:13:-;947:24;2505:16:0;2516:4;2505:10;:16::i;:::-;3536:7:13::1;3531:194;3553:10;:17;3549:1;:21;;;3531:194;;;3589:136;3620:10;3631:1;3620:13;;;;;;;;;;;;;;;;;;;;;;;;:19;;;3657:10;3668:1;3657:13;;;;;;;;;;;;;;;;;;;;;;;;:20;;;3695:10;3706:1;3695:13;;;;;;;;;;;;;;;;;;;;;;;;:16;;;3589:13;:136::i;:::-;3572:3;;;;;:::i;:::-;;;;3531:194;;;;3406:326:::0;;:::o;2930:237::-;947:24;2505:16:0;2516:4;2505:10;:16::i;:::-;3056:7:13::1;3051:109;3073:10;:17;3069:1;:21;;;3051:109;;;3109:51;3121:10;3132:1;3121:13;;;;;;;;;;;;;;;;;;;;;;;;:20;;;3143:10;3154:1;3143:13;;;;;;;;;;;;;;;;;;;;;;;;:16;;;3109:11;:51::i;:::-;3092:3;;;;;:::i;:::-;;;;3051:109;;;;2930:237:::0;;:::o;2700:224::-;1457:32;947:24;1478:10;1457:7;:32::i;:::-;:91;;;;1509:39;2072:4:0;1517:18:13;;1537:10;1509:7;:39::i;:::-;1457:91;1436:159;;;;;;;;;;;;:::i;:::-;;;;;;;;;2847:32:::1;2872:6;2847:24;:32::i;:::-;2897:2;2889:20;;:28;2910:6;2889:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;2700:224:::0;;:::o;2027:49:0:-;2072:4;2027:49;;;:::o;525:54:13:-;;;;;;;;;;;;;;;;;:::o;3173:227::-;1457:32;947:24;1478:10;1457:7;:32::i;:::-;:91;;;;1509:39;2072:4:0;1517:18:13;;1537:10;1509:7;:39::i;:::-;1457:91;1436:159;;;;;;;;;;;;:::i;:::-;;;;;;;;;3304:41:::1;3331:5;3338:6;3304:26;:41::i;:::-;3355:38;3382:2;3386:6;3362:5;3355:26;;;;:38;;;;;:::i;:::-;3173:227:::0;;;:::o;909:62::-;947:24;909:62;:::o;5228:147:0:-;5312:18;5325:4;5312:12;:18::i;:::-;2505:16;2516:4;2505:10;:16::i;:::-;5342:26:::1;5354:4;5360:7;5342:11;:26::i;:::-;5228:147:::0;;;:::o;3738:203:13:-;2072:4:0;3836:18:13;;2505:16:0;2516:4;2505:10;:16::i;:::-;3882:7:13::1;3870:9;:19;;;;3919:15;3899:17;:35;;;;3738:203:::0;;;:::o;684:54::-;;;;;;;;;;;;;;;;;:::o;829:155:10:-;914:4;952:25;937:40;;;:11;:40;;;;930:47;;829:155;;;:::o;3334:103:0:-;3400:30;3411:4;3417:12;:10;:12::i;:::-;3400:10;:30::i;:::-;3334:103;:::o;7461:233::-;7544:22;7552:4;7558:7;7544;:22::i;:::-;7539:149;;7614:4;7582:6;:12;7589:4;7582:12;;;;;;;;;;;:20;;:29;7603:7;7582:29;;;;;;;;;;;;;;;;:36;;;;;;;;;;;;;;;;;;7664:12;:10;:12::i;:::-;7637:40;;7655:7;7637:40;;7649:4;7637:40;;;;;;;;;;7539:149;7461:233;;:::o;640:96:8:-;693:7;719:10;712:17;;640:96;:::o;7865:234:0:-;7948:22;7956:4;7962:7;7948;:22::i;:::-;7944:149;;;8018:5;7986:6;:12;7993:4;7986:12;;;;;;;;;;;:20;;:29;8007:7;7986:29;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;8069:12;:10;:12::i;:::-;8042:40;;8060:7;8042:40;;8054:4;8042:40;;;;;;;;;;7944:149;7865:234;;:::o;1758:407:13:-;1832:39;2072:4:0;1840:18:13;;1860:10;1832:7;:39::i;:::-;1827:332;;1992:17;;1962:6;1912:19;:47;1932:26;1948:9;;1932:15;:26::i;:::-;1912:47;;;;;;;;;;;;:56;;;;:::i;:::-;:97;;1887:190;;;;;;;;;;;;:::i;:::-;;;;;;;;;2142:6;2091:19;:47;2111:26;2127:9;;2111:15;:26::i;:::-;2091:47;;;;;;;;;;;;:57;;;;;;;:::i;:::-;;;;;;;;1827:332;1758:407;:::o;2171:523::-;2274:39;2072:4:0;2282:18:13;;2302:10;2274:7;:39::i;:::-;2269:419;;2468:19;:26;2488:5;2468:26;;;;;;;;;;;;;;;;2438:6;2354:16;:23;2371:5;2354:23;;;;;;;;;;;;;;;:61;2378:36;2394:12;:19;2407:5;2394:19;;;;;;;;;;;;;;;;2378:15;:36::i;:::-;2354:61;;;;;;;;;;;;:90;;;;:::i;:::-;:140;;2329:233;;;;;;;;;;;;:::i;:::-;;;;;;;;;2671:6;2576:16;:23;2593:5;2576:23;;;;;;;;;;;;;;;:91;2617:36;2633:12;:19;2646:5;2633:19;;;;;;;;;;;;;;;;2617:15;:36::i;:::-;2576:91;;;;;;;;;;;;:101;;;;;;;:::i;:::-;;;;;;;;2269:419;2171:523;;:::o;763:205:6:-;875:86;895:5;925:23;;;950:2;954:5;902:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;875:19;:86::i;:::-;763:205;;;:::o;3718:479:0:-;3806:22;3814:4;3820:7;3806;:22::i;:::-;3801:390;;3989:28;4009:7;3989:19;:28::i;:::-;4088:38;4116:4;4108:13;;4123:2;4088:19;:38::i;:::-;3896:252;;;;;;;;;:::i;:::-;;;;;;;;;;;;;3844:336;;;;;;;;;;;:::i;:::-;;;;;;;;3801:390;3718:479;;:::o;3747:706:6:-;4166:23;4192:69;4220:4;4192:69;;;;;;;;;;;;;;;;;4200:5;4192:27;;;;:69;;;;;:::i;:::-;4166:95;;4295:1;4275:10;:17;:21;4271:176;;;4370:10;4359:30;;;;;;;;;;;;:::i;:::-;4351:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;4271:176;3747:706;;;:::o;2102:149:9:-;2160:13;2192:52;2220:4;2204:22;;311:2;2192:52;;:11;:52::i;:::-;2185:59;;2102:149;;;:::o;1513:437::-;1588:13;1613:19;1658:1;1649:6;1645:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;1635:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1613:47;;1670:15;:6;1677:1;1670:9;;;;;;;;;;;;;;;;;;;:15;;;;;;;;;;;1695;:6;1702:1;1695:9;;;;;;;;;;;;;;;;;;;:15;;;;;;;;;;;1725:9;1750:1;1741:6;1737:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;1725:26;;1720:128;1757:1;1753;:5;1720:128;;;1791:8;1808:3;1800:5;:11;1791:21;;;;;;;;;;;;;;;;;;1779:6;1786:1;1779:9;;;;;;;;;;;;;;;;;;;:33;;;;;;;;;;;1836:1;1826:11;;;;;1760:3;;;;:::i;:::-;;;1720:128;;;;1874:1;1865:5;:10;1857:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;1936:6;1922:21;;;1513:437;;;;:::o;3873:223:7:-;4006:12;4037:52;4059:6;4067:4;4073:1;4076:12;4037:21;:52::i;:::-;4030:59;;3873:223;;;;;:::o;4960:446::-;5125:12;5182:5;5157:21;:30;;5149:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;5241:12;5255:23;5282:6;:11;;5301:5;5308:4;5282:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5240:73;;;;5330:69;5357:6;5365:7;5374:10;5386:12;5330:26;:69::i;:::-;5323:76;;;;4960:446;;;;;;:::o;7466:628::-;7646:12;7674:7;7670:418;;;7722:1;7701:10;:17;:22;7697:286;;;7916:18;7927:6;7916:10;:18::i;:::-;7908:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;7697:286;8003:10;7996:17;;;;7670:418;8044:33;8052:10;8064:12;8044:7;:33::i;:::-;7466:628;;;;;;;:::o;1175:320::-;1235:4;1487:1;1465:7;:19;;;:23;1458:30;;1175:320;;;:::o;8616:540::-;8795:1;8775:10;:17;:21;8771:379;;;9003:10;8997:17;9059:15;9046:10;9042:2;9038:19;9031:44;8956:133;9126:12;9119:20;;;;;;;;;;;:::i;:::-;;;;;;;;38:751:15;166:5;191:113;207:96;296:6;207:96;:::i;:::-;191:113;:::i;:::-;182:122;;324:5;353:6;346:5;339:21;387:4;380:5;376:16;369:23;;413:6;463:3;455:4;447:6;443:17;438:3;434:27;431:36;428:2;;;492:1;489;482:12;428:2;528:1;513:270;538:6;535:1;532:13;513:270;;;606:3;635:69;700:3;688:10;635:69;:::i;:::-;630:3;623:82;734:4;729:3;725:14;718:21;;768:4;763:3;759:14;752:21;;573:210;560:1;557;553:9;548:14;;513:270;;;517:14;172:617;;;;;;;:::o;824:745::-;950:5;975:111;991:94;1078:6;991:94;:::i;:::-;975:111;:::i;:::-;966:120;;1106:5;1135:6;1128:5;1121:21;1169:4;1162:5;1158:16;1151:23;;1195:6;1245:3;1237:4;1229:6;1225:17;1220:3;1216:27;1213:36;1210:2;;;1274:1;1271;1264:12;1210:2;1310:1;1295:268;1320:6;1317:1;1314:13;1295:268;;;1388:3;1417:67;1480:3;1468:10;1417:67;:::i;:::-;1412:3;1405:80;1514:4;1509:3;1505:14;1498:21;;1548:4;1543:3;1539:14;1532:21;;1355:208;1342:1;1339;1335:9;1330:14;;1295:268;;;1299:14;956:613;;;;;;;:::o;1575:139::-;1621:5;1659:6;1646:20;1637:29;;1675:33;1702:5;1675:33;:::i;:::-;1627:87;;;;:::o;1751:367::-;1854:5;1903:3;1896:4;1888:6;1884:17;1880:27;1870:2;;1921:1;1918;1911:12;1870:2;1961:6;1948:20;1986:126;2108:3;2100:6;2093:4;2085:6;2081:17;1986:126;:::i;:::-;1977:135;;1860:258;;;;;:::o;2153:363::-;2254:5;2303:3;2296:4;2288:6;2284:17;2280:27;2270:2;;2321:1;2318;2311:12;2270:2;2361:6;2348:20;2386:124;2506:3;2498:6;2491:4;2483:6;2479:17;2386:124;:::i;:::-;2377:133;;2260:256;;;;;:::o;2522:137::-;2576:5;2607:6;2601:13;2592:22;;2623:30;2647:5;2623:30;:::i;:::-;2582:77;;;;:::o;2665:139::-;2711:5;2749:6;2736:20;2727:29;;2765:33;2792:5;2765:33;:::i;:::-;2717:87;;;;:::o;2810:137::-;2855:5;2893:6;2880:20;2871:29;;2909:32;2935:5;2909:32;:::i;:::-;2861:86;;;;:::o;2982:676::-;3063:5;3107:4;3095:9;3090:3;3086:19;3082:30;3079:2;;;3125:1;3122;3115:12;3079:2;3147:21;3163:4;3147:21;:::i;:::-;3138:30;;3228:1;3268:49;3313:3;3304:6;3293:9;3289:22;3268:49;:::i;:::-;3261:4;3254:5;3250:16;3243:75;3178:151;3386:2;3427:49;3472:3;3463:6;3452:9;3448:22;3427:49;:::i;:::-;3420:4;3413:5;3409:16;3402:75;3339:149;3549:2;3590:49;3635:3;3626:6;3615:9;3611:22;3590:49;:::i;:::-;3583:4;3576:5;3572:16;3565:75;3498:153;3069:589;;;;:::o;3691:512::-;3770:5;3814:4;3802:9;3797:3;3793:19;3789:30;3786:2;;;3832:1;3829;3822:12;3786:2;3854:21;3870:4;3854:21;:::i;:::-;3845:30;;3932:1;3972:49;4017:3;4008:6;3997:9;3993:22;3972:49;:::i;:::-;3965:4;3958:5;3954:16;3947:75;3885:148;4094:2;4135:49;4180:3;4171:6;4160:9;4156:22;4135:49;:::i;:::-;4128:4;4121:5;4117:16;4110:75;4043:153;3776:427;;;;:::o;4209:139::-;4255:5;4293:6;4280:20;4271:29;;4309:33;4336:5;4309:33;:::i;:::-;4261:87;;;;:::o;4354:262::-;4413:6;4462:2;4450:9;4441:7;4437:23;4433:32;4430:2;;;4478:1;4475;4468:12;4430:2;4521:1;4546:53;4591:7;4582:6;4571:9;4567:22;4546:53;:::i;:::-;4536:63;;4492:117;4420:196;;;;:::o;4622:407::-;4690:6;4698;4747:2;4735:9;4726:7;4722:23;4718:32;4715:2;;;4763:1;4760;4753:12;4715:2;4806:1;4831:53;4876:7;4867:6;4856:9;4852:22;4831:53;:::i;:::-;4821:63;;4777:117;4933:2;4959:53;5004:7;4995:6;4984:9;4980:22;4959:53;:::i;:::-;4949:63;;4904:118;4705:324;;;;;:::o;5035:552::-;5112:6;5120;5128;5177:2;5165:9;5156:7;5152:23;5148:32;5145:2;;;5193:1;5190;5183:12;5145:2;5236:1;5261:53;5306:7;5297:6;5286:9;5282:22;5261:53;:::i;:::-;5251:63;;5207:117;5363:2;5389:53;5434:7;5425:6;5414:9;5410:22;5389:53;:::i;:::-;5379:63;;5334:118;5491:2;5517:53;5562:7;5553:6;5542:9;5538:22;5517:53;:::i;:::-;5507:63;;5462:118;5135:452;;;;;:::o;5593:552::-;5670:6;5678;5686;5735:2;5723:9;5714:7;5710:23;5706:32;5703:2;;;5751:1;5748;5741:12;5703:2;5794:1;5819:53;5864:7;5855:6;5844:9;5840:22;5819:53;:::i;:::-;5809:63;;5765:117;5921:2;5947:53;5992:7;5983:6;5972:9;5968:22;5947:53;:::i;:::-;5937:63;;5892:118;6049:2;6075:53;6120:7;6111:6;6100:9;6096:22;6075:53;:::i;:::-;6065:63;;6020:118;5693:452;;;;;:::o;6151:469::-;6267:6;6316:2;6304:9;6295:7;6291:23;6287:32;6284:2;;;6332:1;6329;6322:12;6284:2;6403:1;6392:9;6388:17;6375:31;6433:18;6425:6;6422:30;6419:2;;;6465:1;6462;6455:12;6419:2;6493:110;6595:7;6586:6;6575:9;6571:22;6493:110;:::i;:::-;6483:120;;6346:267;6274:346;;;;:::o;6626:465::-;6740:6;6789:2;6777:9;6768:7;6764:23;6760:32;6757:2;;;6805:1;6802;6795:12;6757:2;6876:1;6865:9;6861:17;6848:31;6906:18;6898:6;6895:30;6892:2;;;6938:1;6935;6928:12;6892:2;6966:108;7066:7;7057:6;7046:9;7042:22;6966:108;:::i;:::-;6956:118;;6819:265;6747:344;;;;:::o;7097:278::-;7164:6;7213:2;7201:9;7192:7;7188:23;7184:32;7181:2;;;7229:1;7226;7219:12;7181:2;7272:1;7297:61;7350:7;7341:6;7330:9;7326:22;7297:61;:::i;:::-;7287:71;;7243:125;7171:204;;;;:::o;7381:262::-;7440:6;7489:2;7477:9;7468:7;7464:23;7460:32;7457:2;;;7505:1;7502;7495:12;7457:2;7548:1;7573:53;7618:7;7609:6;7598:9;7594:22;7573:53;:::i;:::-;7563:63;;7519:117;7447:196;;;;:::o;7649:407::-;7717:6;7725;7774:2;7762:9;7753:7;7749:23;7745:32;7742:2;;;7790:1;7787;7780:12;7742:2;7833:1;7858:53;7903:7;7894:6;7883:9;7879:22;7858:53;:::i;:::-;7848:63;;7804:117;7960:2;7986:53;8031:7;8022:6;8011:9;8007:22;7986:53;:::i;:::-;7976:63;;7931:118;7732:324;;;;;:::o;8062:260::-;8120:6;8169:2;8157:9;8148:7;8144:23;8140:32;8137:2;;;8185:1;8182;8175:12;8137:2;8228:1;8253:52;8297:7;8288:6;8277:9;8273:22;8253:52;:::i;:::-;8243:62;;8199:116;8127:195;;;;:::o;8328:262::-;8387:6;8436:2;8424:9;8415:7;8411:23;8407:32;8404:2;;;8452:1;8449;8442:12;8404:2;8495:1;8520:53;8565:7;8556:6;8545:9;8541:22;8520:53;:::i;:::-;8510:63;;8466:117;8394:196;;;;:::o;8596:407::-;8664:6;8672;8721:2;8709:9;8700:7;8696:23;8692:32;8689:2;;;8737:1;8734;8727:12;8689:2;8780:1;8805:53;8850:7;8841:6;8830:9;8826:22;8805:53;:::i;:::-;8795:63;;8751:117;8907:2;8933:53;8978:7;8969:6;8958:9;8954:22;8933:53;:::i;:::-;8923:63;;8878:118;8679:324;;;;;:::o;9009:407::-;9077:6;9085;9134:2;9122:9;9113:7;9109:23;9105:32;9102:2;;;9150:1;9147;9140:12;9102:2;9193:1;9218:53;9263:7;9254:6;9243:9;9239:22;9218:53;:::i;:::-;9208:63;;9164:117;9320:2;9346:53;9391:7;9382:6;9371:9;9367:22;9346:53;:::i;:::-;9336:63;;9291:118;9092:324;;;;;:::o;9422:118::-;9509:24;9527:5;9509:24;:::i;:::-;9504:3;9497:37;9487:53;;:::o;9546:109::-;9627:21;9642:5;9627:21;:::i;:::-;9622:3;9615:34;9605:50;;:::o;9661:118::-;9748:24;9766:5;9748:24;:::i;:::-;9743:3;9736:37;9726:53;;:::o;9785:373::-;9889:3;9917:38;9949:5;9917:38;:::i;:::-;9971:88;10052:6;10047:3;9971:88;:::i;:::-;9964:95;;10068:52;10113:6;10108:3;10101:4;10094:5;10090:16;10068:52;:::i;:::-;10145:6;10140:3;10136:16;10129:23;;9893:265;;;;;:::o;10164:364::-;10252:3;10280:39;10313:5;10280:39;:::i;:::-;10335:71;10399:6;10394:3;10335:71;:::i;:::-;10328:78;;10415:52;10460:6;10455:3;10448:4;10441:5;10437:16;10415:52;:::i;:::-;10492:29;10514:6;10492:29;:::i;:::-;10487:3;10483:39;10476:46;;10256:272;;;;;:::o;10534:377::-;10640:3;10668:39;10701:5;10668:39;:::i;:::-;10723:89;10805:6;10800:3;10723:89;:::i;:::-;10716:96;;10821:52;10866:6;10861:3;10854:4;10847:5;10843:16;10821:52;:::i;:::-;10898:6;10893:3;10889:16;10882:23;;10644:267;;;;;:::o;10917:366::-;11059:3;11080:67;11144:2;11139:3;11080:67;:::i;:::-;11073:74;;11156:93;11245:3;11156:93;:::i;:::-;11274:2;11269:3;11265:12;11258:19;;11063:220;;;:::o;11289:366::-;11431:3;11452:67;11516:2;11511:3;11452:67;:::i;:::-;11445:74;;11528:93;11617:3;11528:93;:::i;:::-;11646:2;11641:3;11637:12;11630:19;;11435:220;;;:::o;11661:366::-;11803:3;11824:67;11888:2;11883:3;11824:67;:::i;:::-;11817:74;;11900:93;11989:3;11900:93;:::i;:::-;12018:2;12013:3;12009:12;12002:19;;11807:220;;;:::o;12033:366::-;12175:3;12196:67;12260:2;12255:3;12196:67;:::i;:::-;12189:74;;12272:93;12361:3;12272:93;:::i;:::-;12390:2;12385:3;12381:12;12374:19;;12179:220;;;:::o;12405:366::-;12547:3;12568:67;12632:2;12627:3;12568:67;:::i;:::-;12561:74;;12644:93;12733:3;12644:93;:::i;:::-;12762:2;12757:3;12753:12;12746:19;;12551:220;;;:::o;12777:402::-;12937:3;12958:85;13040:2;13035:3;12958:85;:::i;:::-;12951:92;;13052:93;13141:3;13052:93;:::i;:::-;13170:2;13165:3;13161:12;13154:19;;12941:238;;;:::o;13185:366::-;13327:3;13348:67;13412:2;13407:3;13348:67;:::i;:::-;13341:74;;13424:93;13513:3;13424:93;:::i;:::-;13542:2;13537:3;13533:12;13526:19;;13331:220;;;:::o;13557:402::-;13717:3;13738:85;13820:2;13815:3;13738:85;:::i;:::-;13731:92;;13832:93;13921:3;13832:93;:::i;:::-;13950:2;13945:3;13941:12;13934:19;;13721:238;;;:::o;13965:366::-;14107:3;14128:67;14192:2;14187:3;14128:67;:::i;:::-;14121:74;;14204:93;14293:3;14204:93;:::i;:::-;14322:2;14317:3;14313:12;14306:19;;14111:220;;;:::o;14337:118::-;14424:24;14442:5;14424:24;:::i;:::-;14419:3;14412:37;14402:53;;:::o;14461:271::-;14591:3;14613:93;14702:3;14693:6;14613:93;:::i;:::-;14606:100;;14723:3;14716:10;;14595:137;;;;:::o;14738:967::-;15120:3;15142:148;15286:3;15142:148;:::i;:::-;15135:155;;15307:95;15398:3;15389:6;15307:95;:::i;:::-;15300:102;;15419:148;15563:3;15419:148;:::i;:::-;15412:155;;15584:95;15675:3;15666:6;15584:95;:::i;:::-;15577:102;;15696:3;15689:10;;15124:581;;;;;:::o;15711:332::-;15832:4;15870:2;15859:9;15855:18;15847:26;;15883:71;15951:1;15940:9;15936:17;15927:6;15883:71;:::i;:::-;15964:72;16032:2;16021:9;16017:18;16008:6;15964:72;:::i;:::-;15837:206;;;;;:::o;16049:210::-;16136:4;16174:2;16163:9;16159:18;16151:26;;16187:65;16249:1;16238:9;16234:17;16225:6;16187:65;:::i;:::-;16141:118;;;;:::o;16265:222::-;16358:4;16396:2;16385:9;16381:18;16373:26;;16409:71;16477:1;16466:9;16462:17;16453:6;16409:71;:::i;:::-;16363:124;;;;:::o;16493:313::-;16606:4;16644:2;16633:9;16629:18;16621:26;;16693:9;16687:4;16683:20;16679:1;16668:9;16664:17;16657:47;16721:78;16794:4;16785:6;16721:78;:::i;:::-;16713:86;;16611:195;;;;:::o;16812:419::-;16978:4;17016:2;17005:9;17001:18;16993:26;;17065:9;17059:4;17055:20;17051:1;17040:9;17036:17;17029:47;17093:131;17219:4;17093:131;:::i;:::-;17085:139;;16983:248;;;:::o;17237:419::-;17403:4;17441:2;17430:9;17426:18;17418:26;;17490:9;17484:4;17480:20;17476:1;17465:9;17461:17;17454:47;17518:131;17644:4;17518:131;:::i;:::-;17510:139;;17408:248;;;:::o;17662:419::-;17828:4;17866:2;17855:9;17851:18;17843:26;;17915:9;17909:4;17905:20;17901:1;17890:9;17886:17;17879:47;17943:131;18069:4;17943:131;:::i;:::-;17935:139;;17833:248;;;:::o;18087:419::-;18253:4;18291:2;18280:9;18276:18;18268:26;;18340:9;18334:4;18330:20;18326:1;18315:9;18311:17;18304:47;18368:131;18494:4;18368:131;:::i;:::-;18360:139;;18258:248;;;:::o;18512:419::-;18678:4;18716:2;18705:9;18701:18;18693:26;;18765:9;18759:4;18755:20;18751:1;18740:9;18736:17;18729:47;18793:131;18919:4;18793:131;:::i;:::-;18785:139;;18683:248;;;:::o;18937:419::-;19103:4;19141:2;19130:9;19126:18;19118:26;;19190:9;19184:4;19180:20;19176:1;19165:9;19161:17;19154:47;19218:131;19344:4;19218:131;:::i;:::-;19210:139;;19108:248;;;:::o;19362:419::-;19528:4;19566:2;19555:9;19551:18;19543:26;;19615:9;19609:4;19605:20;19601:1;19590:9;19586:17;19579:47;19643:131;19769:4;19643:131;:::i;:::-;19635:139;;19533:248;;;:::o;19787:222::-;19880:4;19918:2;19907:9;19903:18;19895:26;;19931:71;19999:1;19988:9;19984:17;19975:6;19931:71;:::i;:::-;19885:124;;;;:::o;20015:129::-;20049:6;20076:20;;:::i;:::-;20066:30;;20105:33;20133:4;20125:6;20105:33;:::i;:::-;20056:88;;;:::o;20150:75::-;20183:6;20216:2;20210:9;20200:19;;20190:35;:::o;20231:343::-;20340:4;20430:18;20422:6;20419:30;20416:2;;;20452:18;;:::i;:::-;20416:2;20502:4;20494:6;20490:17;20482:25;;20562:4;20556;20552:15;20544:23;;20345:229;;;:::o;20580:341::-;20687:4;20777:18;20769:6;20766:30;20763:2;;;20799:18;;:::i;:::-;20763:2;20849:4;20841:6;20837:17;20829:25;;20909:4;20903;20899:15;20891:23;;20692:229;;;:::o;20927:98::-;20978:6;21012:5;21006:12;20996:22;;20985:40;;;:::o;21031:99::-;21083:6;21117:5;21111:12;21101:22;;21090:40;;;:::o;21136:147::-;21237:11;21274:3;21259:18;;21249:34;;;;:::o;21289:169::-;21373:11;21407:6;21402:3;21395:19;21447:4;21442:3;21438:14;21423:29;;21385:73;;;;:::o;21464:148::-;21566:11;21603:3;21588:18;;21578:34;;;;:::o;21618:305::-;21658:3;21677:20;21695:1;21677:20;:::i;:::-;21672:25;;21711:20;21729:1;21711:20;:::i;:::-;21706:25;;21865:1;21797:66;21793:74;21790:1;21787:81;21784:2;;;21871:18;;:::i;:::-;21784:2;21915:1;21912;21908:9;21901:16;;21662:261;;;;:::o;21929:185::-;21969:1;21986:20;22004:1;21986:20;:::i;:::-;21981:25;;22020:20;22038:1;22020:20;:::i;:::-;22015:25;;22059:1;22049:2;;22064:18;;:::i;:::-;22049:2;22106:1;22103;22099:9;22094:14;;21971:143;;;;:::o;22120:348::-;22160:7;22183:20;22201:1;22183:20;:::i;:::-;22178:25;;22217:20;22235:1;22217:20;:::i;:::-;22212:25;;22405:1;22337:66;22333:74;22330:1;22327:81;22322:1;22315:9;22308:17;22304:105;22301:2;;;22412:18;;:::i;:::-;22301:2;22460:1;22457;22453:9;22442:20;;22168:300;;;;:::o;22474:96::-;22511:7;22540:24;22558:5;22540:24;:::i;:::-;22529:35;;22519:51;;;:::o;22576:90::-;22610:7;22653:5;22646:13;22639:21;22628:32;;22618:48;;;:::o;22672:77::-;22709:7;22738:5;22727:16;;22717:32;;;:::o;22755:149::-;22791:7;22831:66;22824:5;22820:78;22809:89;;22799:105;;;:::o;22910:126::-;22947:7;22987:42;22980:5;22976:54;22965:65;;22955:81;;;:::o;23042:77::-;23079:7;23108:5;23097:16;;23087:32;;;:::o;23125:86::-;23160:7;23200:4;23193:5;23189:16;23178:27;;23168:43;;;:::o;23217:307::-;23285:1;23295:113;23309:6;23306:1;23303:13;23295:113;;;23394:1;23389:3;23385:11;23379:18;23375:1;23370:3;23366:11;23359:39;23331:2;23328:1;23324:10;23319:15;;23295:113;;;23426:6;23423:1;23420:13;23417:2;;;23506:1;23497:6;23492:3;23488:16;23481:27;23417:2;23266:258;;;;:::o;23530:171::-;23569:3;23592:24;23610:5;23592:24;:::i;:::-;23583:33;;23638:4;23631:5;23628:15;23625:2;;;23646:18;;:::i;:::-;23625:2;23693:1;23686:5;23682:13;23675:20;;23573:128;;;:::o;23707:281::-;23790:27;23812:4;23790:27;:::i;:::-;23782:6;23778:40;23920:6;23908:10;23905:22;23884:18;23872:10;23869:34;23866:62;23863:2;;;23931:18;;:::i;:::-;23863:2;23971:10;23967:2;23960:22;23750:238;;;:::o;23994:167::-;24031:3;24054:22;24070:5;24054:22;:::i;:::-;24045:31;;24098:4;24091:5;24088:15;24085:2;;;24106:18;;:::i;:::-;24085:2;24153:1;24146:5;24142:13;24135:20;;24035:126;;;:::o;24167:180::-;24215:77;24212:1;24205:88;24312:4;24309:1;24302:15;24336:4;24333:1;24326:15;24353:180;24401:77;24398:1;24391:88;24498:4;24495:1;24488:15;24522:4;24519:1;24512:15;24539:180;24587:77;24584:1;24577:88;24684:4;24681:1;24674:15;24708:4;24705:1;24698:15;24725:102;24766:6;24817:2;24813:7;24808:2;24801:5;24797:14;24793:28;24783:38;;24773:54;;;:::o;24833:182::-;24973:34;24969:1;24961:6;24957:14;24950:58;24939:76;:::o;25021:221::-;25161:34;25157:1;25149:6;25145:14;25138:58;25230:4;25225:2;25217:6;25213:15;25206:29;25127:115;:::o;25248:225::-;25388:34;25384:1;25376:6;25372:14;25365:58;25457:8;25452:2;25444:6;25440:15;25433:33;25354:119;:::o;25479:171::-;25619:23;25615:1;25607:6;25603:14;25596:47;25585:65;:::o;25656:179::-;25796:31;25792:1;25784:6;25780:14;25773:55;25762:73;:::o;25841:173::-;25981:25;25977:1;25969:6;25965:14;25958:49;25947:67;:::o;26020:229::-;26160:34;26156:1;26148:6;26144:14;26137:58;26229:12;26224:2;26216:6;26212:15;26205:37;26126:123;:::o;26255:167::-;26395:19;26391:1;26383:6;26379:14;26372:43;26361:61;:::o;26428:234::-;26568:34;26564:1;26556:6;26552:14;26545:58;26637:17;26632:2;26624:6;26620:15;26613:42;26534:128;:::o;26668:122::-;26741:24;26759:5;26741:24;:::i;:::-;26734:5;26731:35;26721:2;;26780:1;26777;26770:12;26721:2;26711:79;:::o;26796:116::-;26866:21;26881:5;26866:21;:::i;:::-;26859:5;26856:32;26846:2;;26902:1;26899;26892:12;26846:2;26836:76;:::o;26918:122::-;26991:24;27009:5;26991:24;:::i;:::-;26984:5;26981:35;26971:2;;27030:1;27027;27020:12;26971:2;26961:79;:::o;27046:120::-;27118:23;27135:5;27118:23;:::i;:::-;27111:5;27108:34;27098:2;;27156:1;27153;27146:12;27098:2;27088:78;:::o;27172:122::-;27245:24;27263:5;27245:24;:::i;:::-;27238:5;27235:35;27225:2;;27284:1;27281;27274:12;27225:2;27215:79;:::o
Swarm Source
ipfs://26a894b3106162d687782045e5508768d567c2e3fa235a9da293aef0d6ed5e12
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$13.53
Net Worth in ETH
Token Allocations
XDAI
94.92%
ETH
3.29%
BNB
1.53%
Others
0.27%
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| GNO | 94.92% | $0.999274 | 12.8485 | $12.84 | |
| LINEA | 1.54% | $2,958.96 | 0.0000702 | $0.207719 | |
| BSC | 1.53% | $891.42 | 0.000232 | $0.206808 | |
| OP | 0.82% | $2,958.95 | 0.0000375 | $0.110961 | |
| ARB | 0.80% | $2,958.84 | 0.00003651 | $0.108027 | |
| AVAX | 0.22% | $12.11 | 0.002463 | $0.029815 | |
| ARBNOVA | 0.13% | $2,958.68 | 0.00000596 | $0.017634 | |
| POL | 0.04% | $0.127237 | 0.0421 | $0.00535 | |
| CELO | <0.01% | $0.116678 | 0.006901 | $0.000805 |
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.