Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60a08060 | 18254699 | 296 days ago | IN | Create: UniwarTokenImpl | 0 ETH | 0.03722215 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
UniwarTokenImpl
Compiler Version
v0.8.21+commit.d9974bed
Optimization Enabled:
Yes with 200 runs
Other Settings:
shanghai EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.21; import "@upgradeable/token/ERC20/ERC20Upgradeable.sol"; import "@upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol"; import "@upgradeable/security/PausableUpgradeable.sol"; import "@upgradeable/access/AccessControlUpgradeable.sol"; import "@upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol"; import "@v2p/interfaces/IUniswapV2Router02.sol"; import "./UniwarRecoverable.sol"; import "./UniwarConfigurable.sol"; contract UniwarTokenImpl is UniwarRecoverable, UniwarConfigurable, ERC20Upgradeable, ERC20BurnableUpgradeable, PausableUpgradeable, AccessControlUpgradeable, ERC20PermitUpgradeable { bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); enum Swap { None, Buy, Sell } struct Tax { uint256 unibot; uint256 liquidity; uint256 treasury; uint256 burn; } Tax public tax; bool private _inSwapAndLiquify; // Deprecated /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } function initialize(address _config) initializer external { __UniwarRecoverable_init(); __UniwarConfigurable_init_unchained(_config); __ERC20_init("UNIWAR", "UNIWAR"); __ERC20Burnable_init(); __Pausable_init(); __AccessControl_init(); __ERC20Permit_init("UNIWAR"); _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); _grantRole(PAUSER_ROLE, msg.sender); _mint(msg.sender, 1e24); } /// @dev Patch for v0.0.2 function initialize2() reinitializer(2) external { delete tax; } function pause() external onlyRole(PAUSER_ROLE) { _pause(); } function unpause() external onlyRole(PAUSER_ROLE) { _unpause(); } function _transfer(address _from, address _to, uint256 _amount) whenNotPaused internal virtual override { require(!config.glacialBind(_from), "UniwarToken: from address frozen"); require(!config.glacialBind(_to), "UniwarToken: to address frozen"); if (config.highElves(_from) || config.highElves(_to)) { super._transfer(_from, _to, _amount); return; } Swap _swap = Swap.None; address _pair = config.pair(); if (_to == _pair) { _swap = Swap.Sell; } else if (_from == _pair) { _swap = Swap.Buy; } uint256 _unibotTax; uint256 _liquidityTax; uint256 _treasuryTax; uint256 _burnTax; uint256 _totalTax; uint256 _afterTax = _amount; uint8 _phase = config.phase(); if (_swap == Swap.Buy) { ( uint16 _unibotTaxRate, uint16 _liquidityTaxRate, uint16 _treasuryTaxRate, uint16 _burnTaxRate ) = config.buyTaxRates(_phase); _unibotTax = _calcTax(_amount, _unibotTaxRate); _liquidityTax = _calcTax(_amount, _liquidityTaxRate); _treasuryTax = _calcTax(_amount, _treasuryTaxRate); _burnTax = _calcTax(_amount, _burnTaxRate); _totalTax = _unibotTax + _liquidityTax + _treasuryTax + _burnTax; _afterTax = _amount - _totalTax; if (_to != config.router() && _to != _pair) { (uint16 _txMaxLimit, uint16 _walletMaxLimit) = config.buyLimits(_phase); uint256 _txMax; uint256 _walletMax; if (_txMaxLimit > 0) { _txMax = _calcTax(totalSupply(), _txMaxLimit); } else { _txMax = totalSupply(); } if (_walletMaxLimit > 0) { _walletMax = _calcTax(totalSupply(), _walletMaxLimit); } else { _walletMax = totalSupply(); } require(_afterTax <= _txMax, "UniwarToken: buy tx max"); require(balanceOf(_to) + _afterTax <= _walletMax, "UniwarToken: wallet max"); } } else if (_swap == Swap.Sell) { ( uint16 _unibotTaxRate, uint16 _liquidityTaxRate, uint16 _treasuryTaxRate, uint16 _burnTaxRate ) = config.sellTaxRates(_phase); _unibotTax = _calcTax(_amount, _unibotTaxRate); _liquidityTax = _calcTax(_amount, _liquidityTaxRate); _treasuryTax = _calcTax(_amount, _treasuryTaxRate); _burnTax = _calcTax(_amount, _burnTaxRate); _totalTax = _unibotTax + _liquidityTax + _burnTax + _treasuryTax; _afterTax = _amount - _totalTax; if (_from != config.router() && _from != _pair) { (uint16 _txMaxLimit,) = config.sellLimits(_phase); uint256 _txMax; if (_txMaxLimit > 0) { _txMax = _calcTax(totalSupply(), _txMaxLimit); } else { _txMax = totalSupply(); } require(_afterTax <= _txMax, "UniwarToken: sell tx max"); } } tax.unibot += _unibotTax; tax.liquidity += _liquidityTax; tax.treasury += _treasuryTax; tax.burn += _burnTax; super._transfer(_from, _to, _afterTax); if (_totalTax > 0) { super._transfer(_from, address(this), _totalTax); } uint256 _tax = tax.unibot + tax.liquidity + tax.treasury + tax.burn; if (_swap == Swap.None && _tax >= _calcTax(totalSupply(), config.swapThreshold())) { _swapAndLiquify(); } } /// @dev Use if the contract accumulation balance becomes too high and liquify was not triggered function recoverRewards(address _to) external onlyOwner { delete tax; super._transfer(address(this), _to, balanceOf(address(this))); } function liquify() external onlyOwner { _swapAndLiquify(); } function _swapAndLiquify() private { uint256 _unibotTax = tax.unibot; uint256 _liquidityTax = tax.liquidity; uint256 _treasuryTax = tax.treasury; uint256 _burnTax = tax.burn; delete tax; uint256 _taxSum = (_unibotTax + (_liquidityTax / 2)) + _treasuryTax; _swapTokensForEth(_taxSum); uint256 _balance = address(this).balance; uint256 _unibotEth = _balance * _unibotTax / _taxSum; uint256 _liquidityEth = (_balance * (_liquidityTax / 2)) / _taxSum; if (_burnTax > 0) { _burn(address(this), _burnTax); } if (_unibotEth > 0) { _buyUnibot(_unibotEth); } if (_liquidityEth > 0) { _addLiquidity( balanceOf(address(this)), _liquidityEth ); } (bool success,) = payable(config.treasury()).call{value: address(this).balance}(""); require(success, "UniwarToken: treasury transfer failed"); } function _swapTokensForEth(uint256 _tokenAmount) private { IUniswapV2Router02 _router = IUniswapV2Router02(config.router()); _approve(address(this), address(_router), _tokenAmount); address[] memory _path = new address[](2); _path[0] = address(this); _path[1] = _router.WETH(); _router.swapExactTokensForETHSupportingFeeOnTransferTokens( _tokenAmount, 0, _path, address(this), block.timestamp ); } function _buyUnibot(uint256 _ethAmount) private { IUniswapV2Router02 _router = IUniswapV2Router02(config.router()); address[] memory _path = new address[](2); _path[0] = _router.WETH(); _path[1] = config.unibot(); _router.swapExactETHForTokensSupportingFeeOnTransferTokens{ value: _ethAmount }(0, _path, config.controller(), block.timestamp); } function _addLiquidity( uint256 _tokenAmount, uint256 _ethAmount ) private { IUniswapV2Router02 _router = IUniswapV2Router02(config.router()); _approve(address(this), address(_router), _tokenAmount); _router.addLiquidityETH{value: _ethAmount}( address(this), _tokenAmount, 0, 0, config.lp(), block.timestamp ); } function _calcTax(uint256 _amount, uint256 _tax) private pure returns (uint256) { if (_amount == 0 || _tax == 0) return 0; unchecked { return (_amount * _tax) / 10_000; } } receive() external payable {} fallback() external payable {} function _authorizeUpgrade(address _newImplementation) internal onlyOwner override {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "./IERC20Upgradeable.sol"; import "./extensions/IERC20MetadataUpgradeable.sol"; import "../../utils/ContextUpgradeable.sol"; import "../../proxy/utils/Initializable.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]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable { 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}. * * All two of these values are immutable: they can only be set once during * construction. */ function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing { __ERC20_init_unchained(name_, symbol_); } function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { _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 default value returned by this function, unless * it's 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 {} /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[45] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol) pragma solidity ^0.8.0; import "../ERC20Upgradeable.sol"; import "../../../utils/ContextUpgradeable.sol"; import "../../../proxy/utils/Initializable.sol"; /** * @dev Extension of {ERC20} that allows token holders to destroy both their own * tokens and those that they have an allowance for, in a way that can be * recognized off-chain (via event analysis). */ abstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable { function __ERC20Burnable_init() internal onlyInitializing { } function __ERC20Burnable_init_unchained() internal onlyInitializing { } /** * @dev Destroys `amount` tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 amount) public virtual { _burn(_msgSender(), amount); } /** * @dev Destroys `amount` tokens from `account`, deducting from the caller's * allowance. * * See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for ``accounts``'s tokens of at least * `amount`. */ function burnFrom(address account, uint256 amount) public virtual { _spendAllowance(account, _msgSender(), amount); _burn(account, amount); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControlUpgradeable.sol"; import "../utils/ContextUpgradeable.sol"; import "../utils/StringsUpgradeable.sol"; import "../utils/introspection/ERC165Upgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ```solidity * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ```solidity * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules} * to enforce additional security measures for this role. */ abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable { function __AccessControl_init() internal onlyInitializing { } function __AccessControl_init_unchained() internal onlyInitializing { } 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(IAccessControlUpgradeable).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 ", StringsUpgradeable.toHexString(account), " is missing role ", StringsUpgradeable.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()); } } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Permit.sol) pragma solidity ^0.8.0; import "./IERC20PermitUpgradeable.sol"; import "../ERC20Upgradeable.sol"; import "../../../utils/cryptography/ECDSAUpgradeable.sol"; import "../../../utils/cryptography/EIP712Upgradeable.sol"; import "../../../utils/CountersUpgradeable.sol"; import "../../../proxy/utils/Initializable.sol"; /** * @dev Implementation 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. * * _Available since v3.4._ * * @custom:storage-size 51 */ abstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable { using CountersUpgradeable for CountersUpgradeable.Counter; mapping(address => CountersUpgradeable.Counter) private _nonces; // solhint-disable-next-line var-name-mixedcase bytes32 private constant _PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); /** * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`. * However, to ensure consistency with the upgradeable transpiler, we will continue * to reserve a slot. * @custom:oz-renamed-from _PERMIT_TYPEHASH */ // solhint-disable-next-line var-name-mixedcase bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT; /** * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`. * * It's a good idea to use the same `name` that is defined as the ERC20 token name. */ function __ERC20Permit_init(string memory name) internal onlyInitializing { __EIP712_init_unchained(name, "1"); } function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {} /** * @dev See {IERC20Permit-permit}. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual override { require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline)); bytes32 hash = _hashTypedDataV4(structHash); address signer = ECDSAUpgradeable.recover(hash, v, r, s); require(signer == owner, "ERC20Permit: invalid signature"); _approve(owner, spender, value); } /** * @dev See {IERC20Permit-nonces}. */ function nonces(address owner) public view virtual override returns (uint256) { return _nonces[owner].current(); } /** * @dev See {IERC20Permit-DOMAIN_SEPARATOR}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view override returns (bytes32) { return _domainSeparatorV4(); } /** * @dev "Consume a nonce": return the current value and increment. * * _Available since v4.1._ */ function _useNonce(address owner) internal virtual returns (uint256 current) { CountersUpgradeable.Counter storage nonce = _nonces[owner]; current = nonce.current(); nonce.increment(); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
pragma solidity >=0.6.2; import './IUniswapV2Router01.sol'; interface IUniswapV2Router02 is IUniswapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.21; import "@upgradeable/interfaces/IERC20Upgradeable.sol"; import "@upgradeable/access/OwnableUpgradeable.sol"; import "@upgradeable/proxy/utils/UUPSUpgradeable.sol"; abstract contract UniwarRecoverable is OwnableUpgradeable, UUPSUpgradeable { event TokensRecovered(address indexed _token, uint256 indexed _amount, address indexed _to); event EthRecovered(uint256 indexed _amount, address indexed _to); function __UniwarRecoverable_init() internal onlyInitializing { __Ownable_init(); __UUPSUpgradeable_init(); __UniwarRecoverable_init_unchained(); } function __UniwarRecoverable_init_unchained() internal onlyInitializing {} function recoverTokens(address _token, uint256 _amount, address _to) external onlyOwner { require(IERC20Upgradeable(_token).transfer(_to, _amount), "UniwarRecoverable: transfer failed"); emit TokensRecovered(_token, _amount, _to); } function recoverEth(uint256 _amount, address payable _to) external onlyOwner { _to.transfer(_amount); emit EthRecovered(_amount, _to); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.21; import "@upgradeable/access/OwnableUpgradeable.sol"; import "@upgradeable/proxy/utils/UUPSUpgradeable.sol"; import "./interfaces/IUniwarConfig.sol"; abstract contract UniwarConfigurable is OwnableUpgradeable, UUPSUpgradeable { IUniwarConfig public config; event UpdateConfig(address indexed _oldConfig, address indexed _newConfig); function __UniwarConfigurable_init(address _config) internal onlyInitializing { __Ownable_init(); __UUPSUpgradeable_init(); __UniwarConfigurable_init_unchained(_config); } function __UniwarConfigurable_init_unchained(address _config) internal onlyInitializing { _updateConfig(_config); } function updateConfig(address _config) external onlyOwner { _updateConfig(_config); } function _updateConfig(address _newConfig) internal { require(_newConfig != address(0), "UniwarConfigurable: invalid config address"); address _oldConfig = address(config); config = IUniwarConfig(_newConfig); emit UpdateConfig(_oldConfig, _newConfig); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20Upgradeable.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20MetadataUpgradeable is IERC20Upgradeable { /** * @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 v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// 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 IAccessControlUpgradeable { /** * @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.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/MathUpgradeable.sol"; import "./math/SignedMathUpgradeable.sol"; /** * @dev String operations. */ library StringsUpgradeable { 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 = MathUpgradeable.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMathUpgradeable.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, MathUpgradeable.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165Upgradeable.sol"; import "../../proxy/utils/Initializable.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 ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal onlyInitializing { } function __ERC165_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/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 IERC20PermitUpgradeable { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../StringsUpgradeable.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSAUpgradeable { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) { // 32 is the length in bytes of hash, // enforced by the type signature above /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") mstore(0x1c, hash) message := keccak256(0x00, 0x3c) } } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", StringsUpgradeable.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, "\x19\x01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) data := keccak256(ptr, 0x42) } } /** * @dev Returns an Ethereum Signed Data with intended validator, created from a * `validator` and `data` according to the version 0 of EIP-191. * * See {recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x00", validator, data)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol) pragma solidity ^0.8.8; import "./ECDSAUpgradeable.sol"; import "../../interfaces/IERC5267Upgradeable.sol"; import "../../proxy/utils/Initializable.sol"; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding * they need in their contracts using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the * separator from the immutable values, which is cheaper than accessing a cached version in cold storage. * * _Available since v3.4._ * * @custom:storage-size 52 */ abstract contract EIP712Upgradeable is Initializable, IERC5267Upgradeable { bytes32 private constant _TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); /// @custom:oz-renamed-from _HASHED_NAME bytes32 private _hashedName; /// @custom:oz-renamed-from _HASHED_VERSION bytes32 private _hashedVersion; string private _name; string private _version; /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ function __EIP712_init(string memory name, string memory version) internal onlyInitializing { __EIP712_init_unchained(name, version); } function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing { _name = name; _version = version; // Reset prior values in storage if upgrading _hashedName = 0; _hashedVersion = 0; } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { return _buildDomainSeparator(); } function _buildDomainSeparator() private view returns (bytes32) { return keccak256(abi.encode(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash); } /** * @dev See {EIP-5267}. * * _Available since v4.9._ */ function eip712Domain() public view virtual override returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ) { // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized // and the EIP712 domain is not reliable, as it will be missing name and version. require(_hashedName == 0 && _hashedVersion == 0, "EIP712: Uninitialized"); return ( hex"0f", // 01111 _EIP712Name(), _EIP712Version(), block.chainid, address(this), bytes32(0), new uint256[](0) ); } /** * @dev The name parameter for the EIP712 domain. * * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs * are a concern. */ function _EIP712Name() internal virtual view returns (string memory) { return _name; } /** * @dev The version parameter for the EIP712 domain. * * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs * are a concern. */ function _EIP712Version() internal virtual view returns (string memory) { return _version; } /** * @dev The hash of the name parameter for the EIP712 domain. * * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead. */ function _EIP712NameHash() internal view returns (bytes32) { string memory name = _EIP712Name(); if (bytes(name).length > 0) { return keccak256(bytes(name)); } else { // If the name is empty, the contract may have been upgraded without initializing the new storage. // We return the name hash in storage if non-zero, otherwise we assume the name is empty by design. bytes32 hashedName = _hashedName; if (hashedName != 0) { return hashedName; } else { return keccak256(""); } } } /** * @dev The hash of the version parameter for the EIP712 domain. * * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead. */ function _EIP712VersionHash() internal view returns (bytes32) { string memory version = _EIP712Version(); if (bytes(version).length > 0) { return keccak256(bytes(version)); } else { // If the version is empty, the contract may have been upgraded without initializing the new storage. // We return the version hash in storage if non-zero, otherwise we assume the version is empty by design. bytes32 hashedVersion = _hashedVersion; if (hashedVersion != 0) { return hashedVersion; } else { return keccak256(""); } } } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[48] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library CountersUpgradeable { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } }
pragma solidity >=0.6.2; interface IUniswapV2Router01 { function factory() external view returns (address); function WETH() external view returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB); function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountToken, uint amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountA, uint amountB); function removeLiquidityETHWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountToken, uint amountETH); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol) pragma solidity ^0.8.0; import "../token/ERC20/IERC20Upgradeable.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../ERC1967/ERC1967UpgradeUpgradeable.sol"; import "./Initializable.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { function __UUPSUpgradeable_init() internal onlyInitializing { } function __UUPSUpgradeable_init_unchained() internal onlyInitializing { } /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate the implementation's compatibility when performing an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. * * @custom:oz-upgrades-unsafe-allow-reachable delegatecall */ function upgradeTo(address newImplementation) public virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. * * @custom:oz-upgrades-unsafe-allow-reachable delegatecall */ function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.21; interface IUniwarConfig { enum Swap { None, Buy, Sell } enum Forge { x, y, z } struct SwapLimits { uint16 txMax; uint16 walletMax; } struct SwapTaxRates { uint16 unibot; uint16 liquidity; uint16 treasury; uint16 burn; } struct ForgeWeights { uint8 x; uint8 y; uint8 z; } struct ForgeRates { uint16 x; uint16 y; uint16 z; } struct ForgeVaultLockPeriod { uint256 x; uint256 y; uint256 z; } function treasury() external view returns (address); function controller() external view returns (address); function lp() external view returns (address); function router() external view returns (address); function pair() external view returns (address); function unibot() external view returns (address); function uniwar() external view returns (address); function forge() external view returns (address); function phase() external view returns (uint8); function swapThreshold() external view returns (uint16); function glacialBind(address _address) external view returns (bool); function highElves(address _address) external view returns (bool); function buyLimits(uint8) external view returns (uint16, uint16); function sellLimits(uint8) external view returns (uint16, uint16); function buyTaxRates(uint8) external view returns (uint16, uint16, uint16, uint16); function sellTaxRates(uint8) external view returns (uint16, uint16, uint16, uint16); function forgeWeights(uint8) external view returns (uint8, uint8, uint8); function forgeStakingRates(uint8) external view returns (uint16, uint16, uint16); function forgeInstantWithdrawRates(uint8) external view returns (uint16, uint16, uint16); function forgeVaultLockPeriods(uint8) external view returns (uint256, uint256, uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library MathUpgradeable { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMathUpgradeable { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// 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 IERC165Upgradeable { /** * @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.9.0) (interfaces/IERC5267.sol) pragma solidity ^0.8.0; interface IERC5267Upgradeable { /** * @dev MAY be emitted to signal that the domain could have changed. */ event EIP712DomainChanged(); /** * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712 * signature. */ function eip712Domain() external view returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822ProxiableUpgradeable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeaconUpgradeable.sol"; import "../../interfaces/IERC1967Upgradeable.sol"; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/StorageSlotUpgradeable.sol"; import "../utils/Initializable.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ */ abstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable { function __ERC1967Upgrade_init() internal onlyInitializing { } function __ERC1967Upgrade_init_unchained() internal onlyInitializing { } // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { AddressUpgradeable.functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); } } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeaconUpgradeable { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol) pragma solidity ^0.8.0; /** * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC. * * _Available since v4.8.3._ */ interface IERC1967Upgradeable { /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Emitted when the beacon is changed. */ event BeaconUpgraded(address indexed beacon); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } }
{ "remappings": [ "@solmate/=lib/solmate/src/", "@zeppelin/=lib/openzeppelin-contracts/contracts/", "@upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", "@v2p/=lib/v2-periphery/src/", "@v2c/=lib/v2-periphery/lib/v2-core/src/", "@core/=lib/v2-periphery/lib/v2-core/src/", "@uniswap/=lib/v2-periphery/lib/solidity-lib/src/libraries/", "ds-test/=lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/", "solidity-lib/=lib/v2-periphery/lib/solidity-lib/", "solmate/=lib/solmate/src/", "v2-core/=lib/v2-periphery/lib/v2-core/src/", "v2-periphery/=lib/v2-periphery/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "shanghai", "viaIR": true, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"_to","type":"address"}],"name":"EthRecovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_token","type":"address"},{"indexed":true,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"_to","type":"address"}],"name":"TokensRecovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_oldConfig","type":"address"},{"indexed":true,"internalType":"address","name":"_newConfig","type":"address"}],"name":"UpdateConfig","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"config","outputs":[{"internalType":"contract IUniwarConfig","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","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":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_config","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialize2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"liquify","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address payable","name":"_to","type":"address"}],"name":"recoverEth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"}],"name":"recoverRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"recoverTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","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":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tax","outputs":[{"internalType":"uint256","name":"unibot","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"treasury","type":"uint256"},{"internalType":"uint256","name":"burn","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_config","type":"address"}],"name":"updateConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60a08060405234620000df57306080525f549060ff8260081c166200008d575060ff8082160362000052575b6040516144739081620000e482396080518181816116370152818161175e0152611b7e0152f35b60ff90811916175f557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160ff8152a15f6200002b565b62461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b6064820152608490fd5b5f80fdfe6040608081526004908136101561001d575b5050361561001b57005b005b5f91823560e01c80630104cb771461211b57806301ffc9a7146120c657806306fdde0314612015578063095ea7b314611feb57806318160ddd14611fcc57806323b872dd14611f87578063248a9ca314611f5c5780632f2ff15d14611eb1578063313ce56714611e955780633644e51514611e7157806336568abe14611ddf5780633659cfe614611b575780633950935114611b075780633f4ba83a14611a6d57806342966c6814611a4f578063472abf68146119bd5780634f1ef286146116e357806352d1902d146116225780635c975abb146115fd57806361b0a56e146114d75780636cc919c81461140857806370a08231146113d0578063715018a61461137357806374277ada146112f457806379502c55146112cb57806379cc67901461129b5780637ecebe00146112625780638456cb591461120657806384b0196e146110fe5780638da5cb5b146110d557806391d148541461108e57806395d89b4114610fa257806399c8d55614610f65578063a217fddf14610f4a578063a457c2d714610ea6578063a9059cbb14610e6d578063c4d66de814610535578063cb9598c314610511578063d505accf1461035a578063d547741f1461031e578063dd62ed3e146102d5578063e63ab1e9146102965763f2fde38b146102025750610011565b346102925760203660031901126102925761021b61216e565b9161022461265b565b6001600160a01b03831615610240578361023d846126b3565b80f35b906020608492519162461bcd60e51b8352820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152fd5b8280fd5b5050346102d157816003193601126102d157602090517f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a8152f35b5080fd5b5050346102d157806003193601126102d157806020926102f361216e565b6102fb612188565b6001600160a01b03918216835260cb865283832091168252845220549051908152f35b50903461029257806003193601126102925761023d91356103556001610342612188565b93838752610192602052862001546124d3565b6125dd565b508290346102d15760e03660031901126102d15761037661216e565b61037e612188565b906044359260643560843560ff8116810361050d578142116104ca5760018060a01b0390818516928389526101f8602052898920908154916001830190558a519060208201927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98452868d840152858a1660608401528a608084015260a083015260c082015260c0815260e0810181811067ffffffffffffffff8211176104b7578b525190206104629161045a9161043461303c565b908c519161190160f01b83526002830152602282015260c43591604260a4359220612faf565b919091612e97565b1603610474575061023d939450612a04565b606490602087519162461bcd60e51b8352820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152fd5b634e487b7160e01b8b526041875260248bfd5b875162461bcd60e51b8152602081850152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606490fd5b8680fd5b833461053257806003193601126105325761052a61265b565b61023d613df2565b80fd5b50346102925760209081600319360112610e695761055161216e565b84549160ff8360081c161591828093610e5c575b8015610e45575b6105759061313d565b60ff19808516600190811789559484610e34575b506105ac60ff895460081c1661059e816131c2565b6105a7816131c2565b6131c2565b6105b5336126b3565b60ff885460081c16916105c7836131c2565b6105d0836131c2565b6105d9836131c2565b6001600160a01b03908116908115610dde5760c954826bffffffffffffffffffffffff60a01b82161760c955167f76e810363ac8d9117158dae31aa539e037a046e52aa6ed77899fadcb513586498a80a36106326131a0565b9161064861063e6131a0565b916105a7816131c2565b82519067ffffffffffffffff91828111610cd0578061066860cd5461284c565b95601f96878111610d6e575b508a908d888411600114610cee5792610ce3575b50505f19600383901b1c191690881b1760cd555b805190828211610cd05781906106b360ce5461284c565b868111610c63575b508990868311600114610be5578c92610bda575b50505f19600383901b1c191690871b1760ce555b60ff895460081c16906106f5826131c2565b6106fe826131c2565b610707826131c2565b61012e838154169055610719826131c2565b6107216131a0565b61072a836131c2565b61074a8a519361073985612244565b898552603160f81b8b8601526131c2565b805190828211610bc75781906107626101c65461284c565b878111610b56575b508a908d888411600114610ad45792610ac9575b50505f19600383901b1c191690881b176101c6555b8151908111610ab657806101c7926107ab845461284c565b868111610a4a575b5089908683116001146109ce578c926109c3575b50505f19600383901b1c191690871b1790555b876101c455876101c55587805261019290818752878920338a52875260ff888a2054161561097e575b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a91828a52808852888a20338b52885260ff898b20541615610936575b50505033156108f4575060cc5469d3c21bcecceda1000000918282018092116108e1575060cc5533865260ca84528486208181540190558451908152857fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef853393a36108aa578380f35b7f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989261ff0019855416855551908152a15f80808380f35b634e487b7160e01b885260119052602487fd5b855162461bcd60e51b815291820185905260248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260649150fd5b828a528752878920338a52875285888a2091825416179055339033907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8a80a45f8080610840565b888052818752878920338a528752878920868282541617905533338a7f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8180a4610803565b015190505f806107c7565b848d528993507fff6df30967a6a678f565c59a19e91e5c0dbb20cfe9f9bf26d7da6dea0fffa24c9190601f1984168e5b8d828210610a345750508411610a1c575b505050811b0190556107da565b01515f1960f88460031b161c191690555f8080610a0f565b8385015186558d979095019493840193016109fe565b909150838c527fff6df30967a6a678f565c59a19e91e5c0dbb20cfe9f9bf26d7da6dea0fffa24c8680850160051c8201928c8610610aad575b918b91869594930160051c01915b828110610a9f5750506107b3565b8e81558594508b9101610a91565b92508192610a83565b634e487b7160e01b8a526041855260248afd5b015190505f8061077e565b6101c681528b94507f19c96c71c556fd932aa7b67ce36d1523299db8f62f4ed8fa14921904af346663929190601f198516908e5b828210610b3f5750508411610b27575b505050811b016101c655610793565b01515f1960f88460031b161c191690555f8080610b18565b8385015186558e979095019493840193018e610b08565b9091506101c68d527f19c96c71c556fd932aa7b67ce36d1523299db8f62f4ed8fa14921904af3466638780850160051c8201928d8610610bbe575b859493910160051c909101908b908f5b838210610bb05750505061076a565b81558594508c91018f610ba1565b92508192610b91565b634e487b7160e01b8c526041875260248cfd5b015190505f806106cf565b60ce8d528993507fd36cd1c74ef8d7326d8021b776c18fb5a5724b7f7bc93c2f42e43e10ef27d12a9190601f1984168e5b8d828210610c4d5750508411610c35575b505050811b0160ce556106e3565b01515f1960f88460031b161c191690555f8080610c27565b8385015186558d97909501949384019301610c16565b90915060ce8c527fd36cd1c74ef8d7326d8021b776c18fb5a5724b7f7bc93c2f42e43e10ef27d12a8680850160051c8201928c8610610cc7575b918b91869594930160051c01915b828110610cb95750506106bb565b8e81558594508b9101610cab565b92508192610c9d565b634e487b7160e01b8b526041865260248bfd5b015190505f80610688565b60cd81528b94507f83978b4c69c48dd978ab43fe30f077615294f938fb7f936d9eb340e51ea7db2e929190601f198516908e5b828210610d575750508411610d3f575b505050811b0160cd5561069c565b01515f1960f88460031b161c191690555f8080610d31565b8385015186558e979095019493840193018e610d21565b90915060cd8d527f83978b4c69c48dd978ab43fe30f077615294f938fb7f936d9eb340e51ea7db2e8780850160051c8201928d8610610dd5575b859493910160051c909101908b908f5b838210610dc757505050610674565b81558594508c91018f610db8565b92508192610da8565b885162461bcd60e51b8152808601899052602a60248201527f556e69776172436f6e666967757261626c653a20696e76616c696420636f6e666044820152696967206164647265737360b01b6064820152608490fd5b61ffff19166101011788555f610589565b50303b15801561056c575060ff841660011461056c565b50600160ff851610610565565b8380fd5b5050346102d157806003193601126102d157602090610e9f610e8d61216e565b610e95613222565b60243590336132fa565b5160018152f35b508234610532578260031936011261053257610ec061216e565b91836024359233815260cb60205281812060018060a01b0386168252602052205490828210610ef957602085610e9f8585038733612a04565b608490602086519162461bcd60e51b8352820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152fd5b5050346102d157816003193601126102d15751908152602090f35b5050346102d157816003193601126102d15760809061022b549061022c549061022d549061022e5492815194855260208501528301526060820152f35b828434610532578060031936011261053257815191828260ce54610fc58161284c565b908184526020956001918783821691825f1461106757505060011461100b575b5050506110079291610ff891038561227c565b519282849384528301906121bf565b0390f35b919086935060ce83527fd36cd1c74ef8d7326d8021b776c18fb5a5724b7f7bc93c2f42e43e10ef27d12a5b82841061104f5750505082010181610ff8611007610fe5565b8054848a018601528895508794909301928101611036565b60ff19168782015293151560051b86019093019350849250610ff891506110079050610fe5565b50346102925781600319360112610292578160209360ff926110ae612188565b9035825261019286528282206001600160a01b039091168252855220549151911615158152f35b5050346102d157816003193601126102d15760335490516001600160a01b039091168152602090f35b50346102925782600319360112610292576101c45415806111fb575b156111c157611166838361112c612884565b91611135612946565b6111738351936111448561220c565b8385526020928151978897600f60f81b895260e0868a015260e08901906121bf565b91878303908801526121bf565b904660608601523060808601528260a086015284820360c08601528080855193848152019401925b8281106111aa57505050500390f35b83518552869550938101939281019260010161119b565b6020606492519162461bcd60e51b835282015260156024820152741152540dcc4c8e88155b9a5b9a5d1a585b1a5e9959605a1b6044820152fd5b506101c5541561111a565b5050346102d157816003193601126102d15760207f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258916112446122ba565b61124c613222565b61012e805460ff1916600117905551338152a180f35b5050346102d15760203660031901126102d15760209181906001600160a01b0361128a61216e565b1681526101f8845220549051908152f35b5050346102d1573660031901126105325761023d6112b761216e565b602435906112c6823383612b02565b612b94565b5050346102d157816003193601126102d15760c95490516001600160a01b039091168152602090f35b5034610292578160031936011261029257356024359160018060a01b038316809303610e695761132261265b565b83828482821561136a575b839283928392f11561136157507faccd02e4a4a6b8801f5088eeeca2bde732e7eddedd80c98788a262a7af8c40ff8380a380f35b513d84823e3d90fd5b506108fc61132d565b833461053257806003193601126105325761138c61265b565b603380546001600160a01b0319811690915581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b5050346102d15760203660031901126102d15760209181906001600160a01b036113f861216e565b16815260ca845220549051908152f35b50346102925760203660031901126102925761142261216e565b9061142b61265b565b6001600160a01b0391821692831561148157505060c954826bffffffffffffffffffffffff60a01b82161760c955167f76e810363ac8d9117158dae31aa539e037a046e52aa6ed77899fadcb513586498380a380f35b906020608492519162461bcd60e51b8352820152602a60248201527f556e69776172436f6e666967757261626c653a20696e76616c696420636f6e666044820152696967206164647265737360b01b6064820152fd5b5034610292576060366003190112610292576114f161216e565b6044356001600160a01b0381811694602435949093909286900361050d5761151761265b565b1691805163a9059cbb60e01b815285838201528460248201526020816044818a885af19081156115f35787916115c5575b50156115775750507f1d2f361398f0cd1eeefa9bd2e5d156e421a3dac8bafb57871aa221c6676631398480a480f35b906020608492519162461bcd60e51b8352820152602260248201527f556e697761725265636f76657261626c653a207472616e73666572206661696c604482015261195960f21b6064820152fd5b6115e6915060203d81116115ec575b6115de818361227c565b810190613125565b5f611548565b503d6115d4565b82513d89823e3d90fd5b5050346102d157816003193601126102d15760209060ff61012e541690519015158152f35b508234610532578060031936011261053257507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316300361167b57602082515f8051602061441e8339815191528152f35b6020608492519162461bcd60e51b8352820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152fd5b509080600319360112610292576116f861216e565b906024359067ffffffffffffffff82116119b957366023830112156119b957818401356117248161229e565b906117318351928361227c565b80825286602094858401923660248284010111610292578060248893018537840101526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169061178c308314156126fb565b6117a85f8051602061441e83398151915292828454161461275c565b6117b061265b565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156117ea5750505050505061023d91506127bd565b8693949596169085516352d1902d60e01b815287818a81865afa8a9181611986575b5061186b57865162461bcd60e51b8152808a01899052602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608490fd5b9791929395949703611931575090869291611885856127bd565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b8480a2855115801590611929575b6118c2575b50505050505080f35b61191d95660819985a5b195960ca1b837f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c869551986119008a612228565b60278a528901528701525190845af4611917612c9c565b91612ccb565b505f80808381806118b9565b5060016118b4565b835162461bcd60e51b8152908101869052602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608490fd5b9091508881813d83116119b2575b61199e818361227c565b810103126119ae5751905f61180c565b8a80fd5b503d611994565b8480fd5b5050346102d157816003193601126102d15760207f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249891610102845460ff8160081c161580611a42575b611a0f9061313d565b61ffff1916178455611a305f61022b555f61022c555f61022d555f61022e55565b835461ff00191684555160028152a180f35b50600260ff821610611a06565b8382346102d15760203660031901126102d15761023d903533612b94565b508290346102d157816003193601126102d157611a886122ba565b61012e9081549060ff821615611acd575060ff1916905581513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90602090a180f35b606490602086519162461bcd60e51b8352820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152fd5b5050346102d157806003193601126102d157610e9f602092611b50611b2a61216e565b33835260cb86528483206001600160a01b038216845286529184902054602435906129e3565b9033612a04565b50903461029257602080600319360112610e6957611b7361216e565b916001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116611bab308214156126fb565b611bc75f8051602061441e83398151915291838354161461275c565b611bcf61265b565b825191611bdb8361220c565b8783527f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615611c1757505050505061023d91506127bd565b8592939495169084516352d1902d60e01b815286818981865afa899181611dac575b50611c9857855162461bcd60e51b8152808901889052602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608490fd5b9691929495939603611d575750908591611cb1846127bd565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b8380a2845115801590611d50575b611ced575b505050505080f35b611d45948291660819985a5b195960ca1b865196611d0a88612228565b602788527f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c8389015287015281519101845af4611917612c9c565b505f80808381611ce5565b5081611ce0565b845162461bcd60e51b8152908101839052602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608490fd5b9091508781813d8311611dd8575b611dc4818361227c565b81010312611dd45751905f611c39565b8980fd5b503d611dba565b508290346102d157826003193601126102d157611dfa612188565b90336001600160a01b03831603611e16579061023d91356125dd565b608490602085519162461bcd60e51b8352820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152fd5b5050346102d157816003193601126102d157602090611e8e61303c565b9051908152f35b5050346102d157816003193601126102d1576020905160128152f35b50346102925781600319360112610292573590611ecc612188565b9082845261019280602052611ee6600183872001546124d3565b83855260208181528286206001600160a01b039094168087529390528185205460ff1615611f12578480f35b8385526020528084208285526020528320600160ff1982541617905533917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8480a45f8080808480f35b5034610292576020366003190112610292578160209360019235815261019285522001549051908152f35b5050346102d15760603660031901126102d157602090610e9f611fa861216e565b611fb0612188565b60443591611fbf833383612b02565b611fc7613222565b6132fa565b5050346102d157816003193601126102d15760209060cc549051908152f35b5050346102d157806003193601126102d157602090610e9f61200b61216e565b6024359033612a04565b828434610532578060031936011261053257815191828260cd546120388161284c565b908184526020956001918783821691825f1461106757505060011461206a575050506110079291610ff891038561227c565b919086935060cd83527f83978b4c69c48dd978ab43fe30f077615294f938fb7f936d9eb340e51ea7db2e5b8284106120ae5750505082010181610ff8611007610fe5565b8054848a018601528895508794909301928101612095565b503461029257602036600319011261029257359063ffffffff60e01b82168092036102925760209250637965db0b60e01b821491821561210a575b50519015158152f35b6301ffc9a760e01b1491505f612101565b5050346102d15760203660031901126102d15761023d9061213a61216e565b9061214361265b565b61215c5f61022b555f61022c555f61022d555f61022e55565b30845260ca6020528320549030613c65565b600435906001600160a01b038216820361218457565b5f80fd5b602435906001600160a01b038216820361218457565b5f5b8381106121af5750505f910152565b81810151838201526020016121a0565b906020916121d88151809281855285808601910161219e565b601f01601f1916010190565b67ffffffffffffffff81116121f857604052565b634e487b7160e01b5f52604160045260245ffd5b6020810190811067ffffffffffffffff8211176121f857604052565b6060810190811067ffffffffffffffff8211176121f857604052565b6040810190811067ffffffffffffffff8211176121f857604052565b6080810190811067ffffffffffffffff8211176121f857604052565b90601f8019910116810190811067ffffffffffffffff8211176121f857604052565b67ffffffffffffffff81116121f857601f01601f191660200190565b335f9081527fff500504ba9d92ea4e2e56110be0e830e976b3c6848a9987bdc3601b0f6d478a602090815260408083205490927f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a9160ff161561231d5750505050565b61232633612d9c565b9184519061233382612260565b604282528482019260603685378251156124bf57603084538251906001918210156124bf5790607860218501536041915b8183116124525750505061241057604861240c9386936123f0936123e1985198899376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8a8601526123b8815180928c60378901910161219e565b8401917001034b99036b4b9b9b4b733903937b6329607d1b60378401525180938684019061219e565b0103602881018752018561227c565b5192839262461bcd60e51b8452600484015260248301906121bf565b0390fd5b60648486519062461bcd60e51b825280600483015260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b909192600f811660108110156124ab576f181899199a1a9b1b9c1cb0b131b232b360811b901a6124828587612d77565b5360041c928015612497575f19019190612364565b634e487b7160e01b82526011600452602482fd5b634e487b7160e01b83526032600452602483fd5b634e487b7160e01b81526032600452602490fd5b5f908082526020906101928252604092838120338252835260ff8482205416156124fd5750505050565b61250633612d9c565b9184519061251382612260565b604282528482019260603685378251156124bf57603084538251906001918210156124bf5790607860218501536041915b8183116125985750505061241057604861240c9386936123f0936123e1985198899376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8a8601526123b8815180928c60378901910161219e565b909192600f811660108110156124ab576f181899199a1a9b1b9c1cb0b131b232b360811b901a6125c88587612d77565b5360041c928015612497575f19019190612544565b905f9180835261019280602052604084209260018060a01b03169283855260205260ff604085205416612611575b50505050565b818452602052604083208284526020526040832060ff1981541690557ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b339380a45f80808061260b565b6033546001600160a01b0316330361266f57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b603380546001600160a01b039283166001600160a01b0319821681179092559091167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3565b1561270257565b60405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b6064820152608490fd5b1561276357565b60405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b6064820152608490fd5b803b156127f1575f8051602061441e83398151915280546001600160a01b0319166001600160a01b03909216919091179055565b60405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608490fd5b90600182811c9216801561287a575b602083101461286657565b634e487b7160e01b5f52602260045260245ffd5b91607f169161285b565b604051905f826101c69182546128998161284c565b9081845260209460019182811690815f1461292457506001146128c8575b5050506128c69250038361227c565b565b5f9081527f19c96c71c556fd932aa7b67ce36d1523299db8f62f4ed8fa14921904af34666395935091905b81831061290c5750506128c693508201015f80806128b7565b855488840185015294850194879450918301916128f3565b925050506128c694925060ff191682840152151560051b8201015f80806128b7565b604051905f826101c791825461295b8161284c565b9081845260209460019182811690815f146129245750600114612987575050506128c69250038361227c565b5f9081527fff6df30967a6a678f565c59a19e91e5c0dbb20cfe9f9bf26d7da6dea0fffa24c95935091905b8183106129cb5750506128c693508201015f80806128b7565b855488840185015294850194879450918301916129b2565b919082018092116129f057565b634e487b7160e01b5f52601160045260245ffd5b6001600160a01b03908116918215612ab15716918215612a615760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591835f5260cb825260405f20855f5282528060405f2055604051908152a3565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608490fd5b60405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b9060018060a01b038083165f5260cb60205260405f209082165f5260205260405f2054925f198403612b345750505050565b808410612b4f57612b46930391612a04565b5f80808061260b565b60405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606490fd5b6001600160a01b03168015612c4d57805f5260ca60205260405f205491808310612bfd576020817fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef925f9585875260ca84520360408620558060cc540360cc55604051908152a3565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608490fd5b3d15612cc6573d90612cad8261229e565b91612cbb604051938461227c565b82523d5f602084013e565b606090565b91929015612d2d5750815115612cdf575090565b3b15612ce85790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b825190915015612d405750805190602001fd5b60405162461bcd60e51b81526020600482015290819061240c9060248301906121bf565b818102929181159184041417156129f057565b908151811015612d88570160200190565b634e487b7160e01b5f52603260045260245ffd5b60405190612da982612228565b602a8252602082016040368237825115612d8857603090538151600190811015612d8857607860218401536029905b808211612e2c575050612de85790565b606460405162461bcd60e51b815260206004820152602060248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b9091600f81166010811015612e83576f181899199a1a9b1b9c1cb0b131b232b360811b901a612e5b8486612d77565b5360041c918015612e6f575f190190612dd8565b60245f634e487b7160e01b81526011600452fd5b60245f634e487b7160e01b81526032600452fd5b6005811015612f9b5780612ea85750565b60018103612ef55760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606490fd5b60028103612f425760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606490fd5b600314612f4b57565b60405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608490fd5b634e487b7160e01b5f52602160045260245ffd5b9291907f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083116130315791608094939160ff6020946040519485521684840152604083015260608201525f93849182805260015afa156130245781516001600160a01b0381161561301e579190565b50600190565b50604051903d90823e3d90fd5b505050505f90600390565b6130446130b2565b61304c6130fe565b6040519060208201927f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8452604083015260608201524660808201523060a082015260a0815260c0810181811067ffffffffffffffff8211176121f85760405251902090565b6130ba612884565b80519081156130ca576020012090565b50506101c45480156130d95790565b507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47090565b613106612946565b8051908115613116576020012090565b50506101c55480156130d95790565b90816020910312612184575180151581036121845790565b1561314457565b60405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608490fd5b604051906131ad82612244565b60068252652aa724aba0a960d11b6020830152565b156131c957565b60405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608490fd5b60ff61012e541661322f57565b60405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606490fd5b9081602091031261218457516001600160a01b03811681036121845790565b519061ffff8216820361218457565b9190826080910312612184576132aa82613286565b916132b760208201613286565b916132d060606132c960408501613286565b9301613286565b90565b919082039182116129f057565b9190826040910312612184576132d060206132c984613286565b60c95460405163575ac36d60e11b8082526001600160a01b038481166004840152939594939092169190602081602481865afa908115613635575f91613c46575b50613c02576040519081526001600160a01b0383166004820152602081602481855afa908115613635575f91613be3575b50613b9e5760405163b97413ed60e01b8082526001600160a01b0386166004830152909190602083602481855afa928315613635575f93613b7d575b508215613b25575b5050613b1c5760c95460405163a8aa1b3160e01b81526001600160a01b0390911692905f602082600481885afa918215613024578192613afb575b506001600160a01b0384811690831603613ade57506002935b6040516358e4ff3760e11b81529295865f8080808060208a6004818b5afa998a15613ad357829a613a95575b5060038c10159c8d613a815760018d0361384a5750505050505060405193630e17b19b60e21b855260ff86166004860152608085602481875afa968715613635575f94858097819a61380c575b5061ffff6134a8816134a081613498816134b097168b6143f8565b9b16896143f8565b9a16876143f8565b9a16856143f8565b976134d26134cb8a6134c68d6134c68d8d6129e3565b6129e3565b80966132d3565b936040516303e21fa960e61b8152602081600481875afa908115613635575f916137dd575b506001600160a01b038581169116141590816137c6575b50613652575b5050926135819592613570613589999693613581965b61353861022b9687546129e3565b865561354861022c9788546129e3565b875561355861022d998a546129e3565b895561356861022e9b8c546129e3565b8b5584613c65565b80613640575b5050549054906129e3565b9054906129e3565b91612f9b571590816135a5575b5061359d57565b6128c6613df2565b905060cc546004602060018060a01b0360c9541660405192838092630445b66760e01b82525afa908115613635575f916135f2575b509061ffff6135ea9216906143f8565b11155f613596565b906020823d60201161362d575b8161360c6020938361227c565b8101031261053257509061ffff6136256135ea93613286565b9192506135da565b3d91506135ff565b6040513d5f823e3d90fd5b61364b913090613c65565b5f80613576565b60ff6024604092839c999698959a979c51948593849263dde1815560e01b84521660048301525afa908115613635575f908192613792575b5061ffff168015613785576136a461ffff9160cc546143f8565b915b16801561377b576136b99060cc546143f8565b905b85116137365760018060a01b0387165f5260ca6020526136df8560405f20546129e3565b116136f1579290939691945f80613514565b60405162461bcd60e51b815260206004820152601760248201527f556e69776172546f6b656e3a2077616c6c6574206d61780000000000000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601760248201527f556e69776172546f6b656e3a20627579207478206d61780000000000000000006044820152606490fd5b5060cc54906136bb565b5061ffff60cc54916136a6565b61ffff92506137b9915060403d6040116137bf575b6137b1818361227c565b8101906132e0565b9161368a565b503d6137a7565b6001600160a01b038581169116141590505f61350e565b6137ff915060203d602011613805575b6137f7818361227c565b810190613267565b5f6134f7565b503d6137ed565b939750509450965060803d8111613843575b613828818361227c565b810161383391613295565b989096919591929091905f61347d565b503d61381e565b949a939991809893999d509590959c60028d1461387e575b505050509261358195926135706135899996936135819661352a565b94509450975097509394506040519363ae9e212f60e01b855260ff871660048601526080856024818b5afa978815613a7657868796889a613a38575b5061ffff6134a8816134a081613498816138d597168b6143f8565b976138eb6134cb8b6134c68c6134c68d8d6129e3565b936040516303e21fa960e61b8152602081600481875afa908115613635575f91613a19575b506001600160a01b03888116911614159081613a02575b50613934575b8080613862565b60ff6024604092839c999698959a979c5194859384926332ddf05560e11b84521660048301525afa80156136355761ffff915f916139e2575b501680156139d9576139819060cc546143f8565b8411613994579290939691945f8061392d565b60405162461bcd60e51b815260206004820152601860248201527f556e69776172546f6b656e3a2073656c6c207478206d617800000000000000006044820152606490fd5b5060cc54613981565b6139fb915060403d6040116137bf576137b1818361227c565b505f61396d565b6001600160a01b038881169116141590505f613927565b613a32915060203d602011613805576137f7818361227c565b5f613910565b939750509450965060803d8111613a6f575b613a54818361227c565b8101613a5f91613295565b989096919591929091905f6138ba565b503d613a4a565b6040513d88823e3d90fd5b634e487b7160e01b83526021600452602483fd5b9099506020813d602011613acb575b81613ab16020938361227c565b810103126102d1575160ff811681036102d157985f613430565b3d9150613aa4565b6040513d84823e3d90fd5b936001600160a01b03828116908716036134045760019450613404565b613b1591925060203d602011613805576137f7818361227c565b905f6133eb565b6128c692613c65565b6040519081526001600160a01b03841660048201529150602090829060249082905afa908115613635575f91613b5e575b505f806133b0565b613b77915060203d6020116115ec576115de818361227c565b5f613b56565b613b9791935060203d6020116115ec576115de818361227c565b915f6133a8565b60405162461bcd60e51b815260206004820152601e60248201527f556e69776172546f6b656e3a20746f20616464726573732066726f7a656e00006044820152606490fd5b613bfc915060203d6020116115ec576115de818361227c565b5f61336c565b606460405162461bcd60e51b815260206004820152602060248201527f556e69776172546f6b656e3a2066726f6d20616464726573732066726f7a656e6044820152fd5b613c5f915060203d6020116115ec576115de818361227c565b5f61333b565b6001600160a01b03908116918215613d815716918215613d30575f82815260ca602052604081205491808310613cdc57604082827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef95876020965260ca8652038282205586815220818154019055604051908152a3565b60405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608490fd5b60405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608490fd5b8115613dde570490565b634e487b7160e01b5f52601260045260245ffd5b61022b545f61022c549061022d5491613e2f61022e5493613e225f61022b555f61022c555f61022d555f61022e55565b6134c68360011c876129e3565b9260018060a01b03918260c9541690604095865197886303e21fa960e61b9485825281600460209c8d935afa9081156142b7579087918991614382575b5016613e79838230612a04565b8851613e8481612228565b6002815289368c83013730613e988261439f565b5289516315ab88c960e31b81528b81600481865afa908115614378578a9161435b575b5088613ec6836143ac565b91169052813b1561435757613f07899283928c5194858094819363791ac94760e01b83528a600484015283602484015260a0604484015260a48301906143bc565b30606483015242608483015203925af180156142b75761433c575b5090613f3a613f4992613f3f83613f3a479384612d64565b613dd4565b9460011c90612d64565b928061432c575b5080614158575b5081614021575b5050808460049260c954168551938480926361d027b360e01b82525afa918215614017578392839283928392613ff8575b504791165af1613f9d612c9c565b5015613fa7575050565b60849250519062461bcd60e51b82526004820152602560248201527f556e69776172546f6b656e3a207472656173757279207472616e736665722066604482015264185a5b195960da1b6064820152fd5b614010919250883d8a11613805576137f7818361227c565b905f613f8f565b84513d85823e3d90fd5b30845260ca86528484205490868460c9541691600488518094819382525afa90811561414e576004929185918791614131575b501692614062828530612a04565b878560c95416885194858092630189e03560e51b82525afa9283156141275791606093918695938893614107575b5060c492938951968795869463f305d71960e01b865230600487015260248601528a60448601528a60648601521660848401524260a48401525af18015614017576140dc575b80613f5e565b606090813d8111614100575b6140f2818361227c565b810103126102d1575f6140d6565b503d6140e8565b60c49350614121908b3d8d11613805576137f7818361227c565b92614090565b87513d88823e3d90fd5b6141489150893d8b11613805576137f7818361227c565b5f614054565b86513d87823e3d90fd5b8360c954169086518381528881600481865afa908115614322579086918891614305575b50169187519061418b82612228565b6002825288368b84013788516315ab88c960e31b81528a81600481885afa9081156142de5789916142e8575b50876141c28461439f565b9116905288516359e9079b60e11b81528a81600481855afa9081156142de57918b916004969594938b916142c1575b50896141fc856143ac565b911690528a5163f77c479160e01b815295869182905afa9384156142b7578894614298575b50823b15614294579161425b879289948b519687958694859363b6f9de9560e01b85528960048601526080602486015260848501906143bc565b9116604483015242606483015203925af1801561414e57908591614280575b50613f57565b614289906121e4565b610e6957835f61427a565b8780fd5b6142b09194508a3d8c11613805576137f7818361227c565b925f614221565b89513d8a823e3d90fd5b6142d89150833d8511613805576137f7818361227c565b5f6141f1565b8a513d8b823e3d90fd5b6142ff91508b3d8d11613805576137f7818361227c565b5f6141b7565b61431c91508a3d8c11613805576137f7818361227c565b5f61417c565b88513d89823e3d90fd5b6143369030612b94565b5f613f50565b613f4992919761434e613f3a926121e4565b97919250613f22565b8880fd5b61437291508c8d3d10613805576137f7818361227c565b5f613ebb565b8b513d8c823e3d90fd5b61439991508b3d8d11613805576137f7818361227c565b5f613e6c565b805115612d885760200190565b805160011015612d885760400190565b9081518082526020808093019301915f5b8281106143db575050505090565b83516001600160a01b0316855293810193928101926001016143cd565b9081158015614415575b61440f5761271091020490565b50505f90565b50801561440256fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca26469706673582212200d42d3b441f78d89b38894d4b3d79f285ec24905a6574f5b0781ebd46bfabd3164736f6c63430008150033
Deployed Bytecode
0x6040608081526004908136101561001d575b5050361561001b57005b005b5f91823560e01c80630104cb771461211b57806301ffc9a7146120c657806306fdde0314612015578063095ea7b314611feb57806318160ddd14611fcc57806323b872dd14611f87578063248a9ca314611f5c5780632f2ff15d14611eb1578063313ce56714611e955780633644e51514611e7157806336568abe14611ddf5780633659cfe614611b575780633950935114611b075780633f4ba83a14611a6d57806342966c6814611a4f578063472abf68146119bd5780634f1ef286146116e357806352d1902d146116225780635c975abb146115fd57806361b0a56e146114d75780636cc919c81461140857806370a08231146113d0578063715018a61461137357806374277ada146112f457806379502c55146112cb57806379cc67901461129b5780637ecebe00146112625780638456cb591461120657806384b0196e146110fe5780638da5cb5b146110d557806391d148541461108e57806395d89b4114610fa257806399c8d55614610f65578063a217fddf14610f4a578063a457c2d714610ea6578063a9059cbb14610e6d578063c4d66de814610535578063cb9598c314610511578063d505accf1461035a578063d547741f1461031e578063dd62ed3e146102d5578063e63ab1e9146102965763f2fde38b146102025750610011565b346102925760203660031901126102925761021b61216e565b9161022461265b565b6001600160a01b03831615610240578361023d846126b3565b80f35b906020608492519162461bcd60e51b8352820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152fd5b8280fd5b5050346102d157816003193601126102d157602090517f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a8152f35b5080fd5b5050346102d157806003193601126102d157806020926102f361216e565b6102fb612188565b6001600160a01b03918216835260cb865283832091168252845220549051908152f35b50903461029257806003193601126102925761023d91356103556001610342612188565b93838752610192602052862001546124d3565b6125dd565b508290346102d15760e03660031901126102d15761037661216e565b61037e612188565b906044359260643560843560ff8116810361050d578142116104ca5760018060a01b0390818516928389526101f8602052898920908154916001830190558a519060208201927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98452868d840152858a1660608401528a608084015260a083015260c082015260c0815260e0810181811067ffffffffffffffff8211176104b7578b525190206104629161045a9161043461303c565b908c519161190160f01b83526002830152602282015260c43591604260a4359220612faf565b919091612e97565b1603610474575061023d939450612a04565b606490602087519162461bcd60e51b8352820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152fd5b634e487b7160e01b8b526041875260248bfd5b875162461bcd60e51b8152602081850152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606490fd5b8680fd5b833461053257806003193601126105325761052a61265b565b61023d613df2565b80fd5b50346102925760209081600319360112610e695761055161216e565b84549160ff8360081c161591828093610e5c575b8015610e45575b6105759061313d565b60ff19808516600190811789559484610e34575b506105ac60ff895460081c1661059e816131c2565b6105a7816131c2565b6131c2565b6105b5336126b3565b60ff885460081c16916105c7836131c2565b6105d0836131c2565b6105d9836131c2565b6001600160a01b03908116908115610dde5760c954826bffffffffffffffffffffffff60a01b82161760c955167f76e810363ac8d9117158dae31aa539e037a046e52aa6ed77899fadcb513586498a80a36106326131a0565b9161064861063e6131a0565b916105a7816131c2565b82519067ffffffffffffffff91828111610cd0578061066860cd5461284c565b95601f96878111610d6e575b508a908d888411600114610cee5792610ce3575b50505f19600383901b1c191690881b1760cd555b805190828211610cd05781906106b360ce5461284c565b868111610c63575b508990868311600114610be5578c92610bda575b50505f19600383901b1c191690871b1760ce555b60ff895460081c16906106f5826131c2565b6106fe826131c2565b610707826131c2565b61012e838154169055610719826131c2565b6107216131a0565b61072a836131c2565b61074a8a519361073985612244565b898552603160f81b8b8601526131c2565b805190828211610bc75781906107626101c65461284c565b878111610b56575b508a908d888411600114610ad45792610ac9575b50505f19600383901b1c191690881b176101c6555b8151908111610ab657806101c7926107ab845461284c565b868111610a4a575b5089908683116001146109ce578c926109c3575b50505f19600383901b1c191690871b1790555b876101c455876101c55587805261019290818752878920338a52875260ff888a2054161561097e575b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a91828a52808852888a20338b52885260ff898b20541615610936575b50505033156108f4575060cc5469d3c21bcecceda1000000918282018092116108e1575060cc5533865260ca84528486208181540190558451908152857fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef853393a36108aa578380f35b7f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989261ff0019855416855551908152a15f80808380f35b634e487b7160e01b885260119052602487fd5b855162461bcd60e51b815291820185905260248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260649150fd5b828a528752878920338a52875285888a2091825416179055339033907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8a80a45f8080610840565b888052818752878920338a528752878920868282541617905533338a7f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8180a4610803565b015190505f806107c7565b848d528993507fff6df30967a6a678f565c59a19e91e5c0dbb20cfe9f9bf26d7da6dea0fffa24c9190601f1984168e5b8d828210610a345750508411610a1c575b505050811b0190556107da565b01515f1960f88460031b161c191690555f8080610a0f565b8385015186558d979095019493840193016109fe565b909150838c527fff6df30967a6a678f565c59a19e91e5c0dbb20cfe9f9bf26d7da6dea0fffa24c8680850160051c8201928c8610610aad575b918b91869594930160051c01915b828110610a9f5750506107b3565b8e81558594508b9101610a91565b92508192610a83565b634e487b7160e01b8a526041855260248afd5b015190505f8061077e565b6101c681528b94507f19c96c71c556fd932aa7b67ce36d1523299db8f62f4ed8fa14921904af346663929190601f198516908e5b828210610b3f5750508411610b27575b505050811b016101c655610793565b01515f1960f88460031b161c191690555f8080610b18565b8385015186558e979095019493840193018e610b08565b9091506101c68d527f19c96c71c556fd932aa7b67ce36d1523299db8f62f4ed8fa14921904af3466638780850160051c8201928d8610610bbe575b859493910160051c909101908b908f5b838210610bb05750505061076a565b81558594508c91018f610ba1565b92508192610b91565b634e487b7160e01b8c526041875260248cfd5b015190505f806106cf565b60ce8d528993507fd36cd1c74ef8d7326d8021b776c18fb5a5724b7f7bc93c2f42e43e10ef27d12a9190601f1984168e5b8d828210610c4d5750508411610c35575b505050811b0160ce556106e3565b01515f1960f88460031b161c191690555f8080610c27565b8385015186558d97909501949384019301610c16565b90915060ce8c527fd36cd1c74ef8d7326d8021b776c18fb5a5724b7f7bc93c2f42e43e10ef27d12a8680850160051c8201928c8610610cc7575b918b91869594930160051c01915b828110610cb95750506106bb565b8e81558594508b9101610cab565b92508192610c9d565b634e487b7160e01b8b526041865260248bfd5b015190505f80610688565b60cd81528b94507f83978b4c69c48dd978ab43fe30f077615294f938fb7f936d9eb340e51ea7db2e929190601f198516908e5b828210610d575750508411610d3f575b505050811b0160cd5561069c565b01515f1960f88460031b161c191690555f8080610d31565b8385015186558e979095019493840193018e610d21565b90915060cd8d527f83978b4c69c48dd978ab43fe30f077615294f938fb7f936d9eb340e51ea7db2e8780850160051c8201928d8610610dd5575b859493910160051c909101908b908f5b838210610dc757505050610674565b81558594508c91018f610db8565b92508192610da8565b885162461bcd60e51b8152808601899052602a60248201527f556e69776172436f6e666967757261626c653a20696e76616c696420636f6e666044820152696967206164647265737360b01b6064820152608490fd5b61ffff19166101011788555f610589565b50303b15801561056c575060ff841660011461056c565b50600160ff851610610565565b8380fd5b5050346102d157806003193601126102d157602090610e9f610e8d61216e565b610e95613222565b60243590336132fa565b5160018152f35b508234610532578260031936011261053257610ec061216e565b91836024359233815260cb60205281812060018060a01b0386168252602052205490828210610ef957602085610e9f8585038733612a04565b608490602086519162461bcd60e51b8352820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152fd5b5050346102d157816003193601126102d15751908152602090f35b5050346102d157816003193601126102d15760809061022b549061022c549061022d549061022e5492815194855260208501528301526060820152f35b828434610532578060031936011261053257815191828260ce54610fc58161284c565b908184526020956001918783821691825f1461106757505060011461100b575b5050506110079291610ff891038561227c565b519282849384528301906121bf565b0390f35b919086935060ce83527fd36cd1c74ef8d7326d8021b776c18fb5a5724b7f7bc93c2f42e43e10ef27d12a5b82841061104f5750505082010181610ff8611007610fe5565b8054848a018601528895508794909301928101611036565b60ff19168782015293151560051b86019093019350849250610ff891506110079050610fe5565b50346102925781600319360112610292578160209360ff926110ae612188565b9035825261019286528282206001600160a01b039091168252855220549151911615158152f35b5050346102d157816003193601126102d15760335490516001600160a01b039091168152602090f35b50346102925782600319360112610292576101c45415806111fb575b156111c157611166838361112c612884565b91611135612946565b6111738351936111448561220c565b8385526020928151978897600f60f81b895260e0868a015260e08901906121bf565b91878303908801526121bf565b904660608601523060808601528260a086015284820360c08601528080855193848152019401925b8281106111aa57505050500390f35b83518552869550938101939281019260010161119b565b6020606492519162461bcd60e51b835282015260156024820152741152540dcc4c8e88155b9a5b9a5d1a585b1a5e9959605a1b6044820152fd5b506101c5541561111a565b5050346102d157816003193601126102d15760207f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258916112446122ba565b61124c613222565b61012e805460ff1916600117905551338152a180f35b5050346102d15760203660031901126102d15760209181906001600160a01b0361128a61216e565b1681526101f8845220549051908152f35b5050346102d1573660031901126105325761023d6112b761216e565b602435906112c6823383612b02565b612b94565b5050346102d157816003193601126102d15760c95490516001600160a01b039091168152602090f35b5034610292578160031936011261029257356024359160018060a01b038316809303610e695761132261265b565b83828482821561136a575b839283928392f11561136157507faccd02e4a4a6b8801f5088eeeca2bde732e7eddedd80c98788a262a7af8c40ff8380a380f35b513d84823e3d90fd5b506108fc61132d565b833461053257806003193601126105325761138c61265b565b603380546001600160a01b0319811690915581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b5050346102d15760203660031901126102d15760209181906001600160a01b036113f861216e565b16815260ca845220549051908152f35b50346102925760203660031901126102925761142261216e565b9061142b61265b565b6001600160a01b0391821692831561148157505060c954826bffffffffffffffffffffffff60a01b82161760c955167f76e810363ac8d9117158dae31aa539e037a046e52aa6ed77899fadcb513586498380a380f35b906020608492519162461bcd60e51b8352820152602a60248201527f556e69776172436f6e666967757261626c653a20696e76616c696420636f6e666044820152696967206164647265737360b01b6064820152fd5b5034610292576060366003190112610292576114f161216e565b6044356001600160a01b0381811694602435949093909286900361050d5761151761265b565b1691805163a9059cbb60e01b815285838201528460248201526020816044818a885af19081156115f35787916115c5575b50156115775750507f1d2f361398f0cd1eeefa9bd2e5d156e421a3dac8bafb57871aa221c6676631398480a480f35b906020608492519162461bcd60e51b8352820152602260248201527f556e697761725265636f76657261626c653a207472616e73666572206661696c604482015261195960f21b6064820152fd5b6115e6915060203d81116115ec575b6115de818361227c565b810190613125565b5f611548565b503d6115d4565b82513d89823e3d90fd5b5050346102d157816003193601126102d15760209060ff61012e541690519015158152f35b508234610532578060031936011261053257507f000000000000000000000000336162df3a9480b4cac9ea6b549f97041c7e75c76001600160a01b0316300361167b57602082515f8051602061441e8339815191528152f35b6020608492519162461bcd60e51b8352820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152fd5b509080600319360112610292576116f861216e565b906024359067ffffffffffffffff82116119b957366023830112156119b957818401356117248161229e565b906117318351928361227c565b80825286602094858401923660248284010111610292578060248893018537840101526001600160a01b037f000000000000000000000000336162df3a9480b4cac9ea6b549f97041c7e75c781169061178c308314156126fb565b6117a85f8051602061441e83398151915292828454161461275c565b6117b061265b565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156117ea5750505050505061023d91506127bd565b8693949596169085516352d1902d60e01b815287818a81865afa8a9181611986575b5061186b57865162461bcd60e51b8152808a01899052602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608490fd5b9791929395949703611931575090869291611885856127bd565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b8480a2855115801590611929575b6118c2575b50505050505080f35b61191d95660819985a5b195960ca1b837f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c869551986119008a612228565b60278a528901528701525190845af4611917612c9c565b91612ccb565b505f80808381806118b9565b5060016118b4565b835162461bcd60e51b8152908101869052602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608490fd5b9091508881813d83116119b2575b61199e818361227c565b810103126119ae5751905f61180c565b8a80fd5b503d611994565b8480fd5b5050346102d157816003193601126102d15760207f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249891610102845460ff8160081c161580611a42575b611a0f9061313d565b61ffff1916178455611a305f61022b555f61022c555f61022d555f61022e55565b835461ff00191684555160028152a180f35b50600260ff821610611a06565b8382346102d15760203660031901126102d15761023d903533612b94565b508290346102d157816003193601126102d157611a886122ba565b61012e9081549060ff821615611acd575060ff1916905581513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90602090a180f35b606490602086519162461bcd60e51b8352820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152fd5b5050346102d157806003193601126102d157610e9f602092611b50611b2a61216e565b33835260cb86528483206001600160a01b038216845286529184902054602435906129e3565b9033612a04565b50903461029257602080600319360112610e6957611b7361216e565b916001600160a01b037f000000000000000000000000336162df3a9480b4cac9ea6b549f97041c7e75c78116611bab308214156126fb565b611bc75f8051602061441e83398151915291838354161461275c565b611bcf61265b565b825191611bdb8361220c565b8783527f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615611c1757505050505061023d91506127bd565b8592939495169084516352d1902d60e01b815286818981865afa899181611dac575b50611c9857855162461bcd60e51b8152808901889052602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608490fd5b9691929495939603611d575750908591611cb1846127bd565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b8380a2845115801590611d50575b611ced575b505050505080f35b611d45948291660819985a5b195960ca1b865196611d0a88612228565b602788527f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c8389015287015281519101845af4611917612c9c565b505f80808381611ce5565b5081611ce0565b845162461bcd60e51b8152908101839052602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608490fd5b9091508781813d8311611dd8575b611dc4818361227c565b81010312611dd45751905f611c39565b8980fd5b503d611dba565b508290346102d157826003193601126102d157611dfa612188565b90336001600160a01b03831603611e16579061023d91356125dd565b608490602085519162461bcd60e51b8352820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152fd5b5050346102d157816003193601126102d157602090611e8e61303c565b9051908152f35b5050346102d157816003193601126102d1576020905160128152f35b50346102925781600319360112610292573590611ecc612188565b9082845261019280602052611ee6600183872001546124d3565b83855260208181528286206001600160a01b039094168087529390528185205460ff1615611f12578480f35b8385526020528084208285526020528320600160ff1982541617905533917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8480a45f8080808480f35b5034610292576020366003190112610292578160209360019235815261019285522001549051908152f35b5050346102d15760603660031901126102d157602090610e9f611fa861216e565b611fb0612188565b60443591611fbf833383612b02565b611fc7613222565b6132fa565b5050346102d157816003193601126102d15760209060cc549051908152f35b5050346102d157806003193601126102d157602090610e9f61200b61216e565b6024359033612a04565b828434610532578060031936011261053257815191828260cd546120388161284c565b908184526020956001918783821691825f1461106757505060011461206a575050506110079291610ff891038561227c565b919086935060cd83527f83978b4c69c48dd978ab43fe30f077615294f938fb7f936d9eb340e51ea7db2e5b8284106120ae5750505082010181610ff8611007610fe5565b8054848a018601528895508794909301928101612095565b503461029257602036600319011261029257359063ffffffff60e01b82168092036102925760209250637965db0b60e01b821491821561210a575b50519015158152f35b6301ffc9a760e01b1491505f612101565b5050346102d15760203660031901126102d15761023d9061213a61216e565b9061214361265b565b61215c5f61022b555f61022c555f61022d555f61022e55565b30845260ca6020528320549030613c65565b600435906001600160a01b038216820361218457565b5f80fd5b602435906001600160a01b038216820361218457565b5f5b8381106121af5750505f910152565b81810151838201526020016121a0565b906020916121d88151809281855285808601910161219e565b601f01601f1916010190565b67ffffffffffffffff81116121f857604052565b634e487b7160e01b5f52604160045260245ffd5b6020810190811067ffffffffffffffff8211176121f857604052565b6060810190811067ffffffffffffffff8211176121f857604052565b6040810190811067ffffffffffffffff8211176121f857604052565b6080810190811067ffffffffffffffff8211176121f857604052565b90601f8019910116810190811067ffffffffffffffff8211176121f857604052565b67ffffffffffffffff81116121f857601f01601f191660200190565b335f9081527fff500504ba9d92ea4e2e56110be0e830e976b3c6848a9987bdc3601b0f6d478a602090815260408083205490927f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a9160ff161561231d5750505050565b61232633612d9c565b9184519061233382612260565b604282528482019260603685378251156124bf57603084538251906001918210156124bf5790607860218501536041915b8183116124525750505061241057604861240c9386936123f0936123e1985198899376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8a8601526123b8815180928c60378901910161219e565b8401917001034b99036b4b9b9b4b733903937b6329607d1b60378401525180938684019061219e565b0103602881018752018561227c565b5192839262461bcd60e51b8452600484015260248301906121bf565b0390fd5b60648486519062461bcd60e51b825280600483015260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b909192600f811660108110156124ab576f181899199a1a9b1b9c1cb0b131b232b360811b901a6124828587612d77565b5360041c928015612497575f19019190612364565b634e487b7160e01b82526011600452602482fd5b634e487b7160e01b83526032600452602483fd5b634e487b7160e01b81526032600452602490fd5b5f908082526020906101928252604092838120338252835260ff8482205416156124fd5750505050565b61250633612d9c565b9184519061251382612260565b604282528482019260603685378251156124bf57603084538251906001918210156124bf5790607860218501536041915b8183116125985750505061241057604861240c9386936123f0936123e1985198899376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8a8601526123b8815180928c60378901910161219e565b909192600f811660108110156124ab576f181899199a1a9b1b9c1cb0b131b232b360811b901a6125c88587612d77565b5360041c928015612497575f19019190612544565b905f9180835261019280602052604084209260018060a01b03169283855260205260ff604085205416612611575b50505050565b818452602052604083208284526020526040832060ff1981541690557ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b339380a45f80808061260b565b6033546001600160a01b0316330361266f57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b603380546001600160a01b039283166001600160a01b0319821681179092559091167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3565b1561270257565b60405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b6064820152608490fd5b1561276357565b60405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b6064820152608490fd5b803b156127f1575f8051602061441e83398151915280546001600160a01b0319166001600160a01b03909216919091179055565b60405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608490fd5b90600182811c9216801561287a575b602083101461286657565b634e487b7160e01b5f52602260045260245ffd5b91607f169161285b565b604051905f826101c69182546128998161284c565b9081845260209460019182811690815f1461292457506001146128c8575b5050506128c69250038361227c565b565b5f9081527f19c96c71c556fd932aa7b67ce36d1523299db8f62f4ed8fa14921904af34666395935091905b81831061290c5750506128c693508201015f80806128b7565b855488840185015294850194879450918301916128f3565b925050506128c694925060ff191682840152151560051b8201015f80806128b7565b604051905f826101c791825461295b8161284c565b9081845260209460019182811690815f146129245750600114612987575050506128c69250038361227c565b5f9081527fff6df30967a6a678f565c59a19e91e5c0dbb20cfe9f9bf26d7da6dea0fffa24c95935091905b8183106129cb5750506128c693508201015f80806128b7565b855488840185015294850194879450918301916129b2565b919082018092116129f057565b634e487b7160e01b5f52601160045260245ffd5b6001600160a01b03908116918215612ab15716918215612a615760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591835f5260cb825260405f20855f5282528060405f2055604051908152a3565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608490fd5b60405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b9060018060a01b038083165f5260cb60205260405f209082165f5260205260405f2054925f198403612b345750505050565b808410612b4f57612b46930391612a04565b5f80808061260b565b60405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606490fd5b6001600160a01b03168015612c4d57805f5260ca60205260405f205491808310612bfd576020817fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef925f9585875260ca84520360408620558060cc540360cc55604051908152a3565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608490fd5b3d15612cc6573d90612cad8261229e565b91612cbb604051938461227c565b82523d5f602084013e565b606090565b91929015612d2d5750815115612cdf575090565b3b15612ce85790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b825190915015612d405750805190602001fd5b60405162461bcd60e51b81526020600482015290819061240c9060248301906121bf565b818102929181159184041417156129f057565b908151811015612d88570160200190565b634e487b7160e01b5f52603260045260245ffd5b60405190612da982612228565b602a8252602082016040368237825115612d8857603090538151600190811015612d8857607860218401536029905b808211612e2c575050612de85790565b606460405162461bcd60e51b815260206004820152602060248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b9091600f81166010811015612e83576f181899199a1a9b1b9c1cb0b131b232b360811b901a612e5b8486612d77565b5360041c918015612e6f575f190190612dd8565b60245f634e487b7160e01b81526011600452fd5b60245f634e487b7160e01b81526032600452fd5b6005811015612f9b5780612ea85750565b60018103612ef55760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606490fd5b60028103612f425760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606490fd5b600314612f4b57565b60405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608490fd5b634e487b7160e01b5f52602160045260245ffd5b9291907f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083116130315791608094939160ff6020946040519485521684840152604083015260608201525f93849182805260015afa156130245781516001600160a01b0381161561301e579190565b50600190565b50604051903d90823e3d90fd5b505050505f90600390565b6130446130b2565b61304c6130fe565b6040519060208201927f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8452604083015260608201524660808201523060a082015260a0815260c0810181811067ffffffffffffffff8211176121f85760405251902090565b6130ba612884565b80519081156130ca576020012090565b50506101c45480156130d95790565b507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47090565b613106612946565b8051908115613116576020012090565b50506101c55480156130d95790565b90816020910312612184575180151581036121845790565b1561314457565b60405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608490fd5b604051906131ad82612244565b60068252652aa724aba0a960d11b6020830152565b156131c957565b60405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608490fd5b60ff61012e541661322f57565b60405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606490fd5b9081602091031261218457516001600160a01b03811681036121845790565b519061ffff8216820361218457565b9190826080910312612184576132aa82613286565b916132b760208201613286565b916132d060606132c960408501613286565b9301613286565b90565b919082039182116129f057565b9190826040910312612184576132d060206132c984613286565b60c95460405163575ac36d60e11b8082526001600160a01b038481166004840152939594939092169190602081602481865afa908115613635575f91613c46575b50613c02576040519081526001600160a01b0383166004820152602081602481855afa908115613635575f91613be3575b50613b9e5760405163b97413ed60e01b8082526001600160a01b0386166004830152909190602083602481855afa928315613635575f93613b7d575b508215613b25575b5050613b1c5760c95460405163a8aa1b3160e01b81526001600160a01b0390911692905f602082600481885afa918215613024578192613afb575b506001600160a01b0384811690831603613ade57506002935b6040516358e4ff3760e11b81529295865f8080808060208a6004818b5afa998a15613ad357829a613a95575b5060038c10159c8d613a815760018d0361384a5750505050505060405193630e17b19b60e21b855260ff86166004860152608085602481875afa968715613635575f94858097819a61380c575b5061ffff6134a8816134a081613498816134b097168b6143f8565b9b16896143f8565b9a16876143f8565b9a16856143f8565b976134d26134cb8a6134c68d6134c68d8d6129e3565b6129e3565b80966132d3565b936040516303e21fa960e61b8152602081600481875afa908115613635575f916137dd575b506001600160a01b038581169116141590816137c6575b50613652575b5050926135819592613570613589999693613581965b61353861022b9687546129e3565b865561354861022c9788546129e3565b875561355861022d998a546129e3565b895561356861022e9b8c546129e3565b8b5584613c65565b80613640575b5050549054906129e3565b9054906129e3565b91612f9b571590816135a5575b5061359d57565b6128c6613df2565b905060cc546004602060018060a01b0360c9541660405192838092630445b66760e01b82525afa908115613635575f916135f2575b509061ffff6135ea9216906143f8565b11155f613596565b906020823d60201161362d575b8161360c6020938361227c565b8101031261053257509061ffff6136256135ea93613286565b9192506135da565b3d91506135ff565b6040513d5f823e3d90fd5b61364b913090613c65565b5f80613576565b60ff6024604092839c999698959a979c51948593849263dde1815560e01b84521660048301525afa908115613635575f908192613792575b5061ffff168015613785576136a461ffff9160cc546143f8565b915b16801561377b576136b99060cc546143f8565b905b85116137365760018060a01b0387165f5260ca6020526136df8560405f20546129e3565b116136f1579290939691945f80613514565b60405162461bcd60e51b815260206004820152601760248201527f556e69776172546f6b656e3a2077616c6c6574206d61780000000000000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601760248201527f556e69776172546f6b656e3a20627579207478206d61780000000000000000006044820152606490fd5b5060cc54906136bb565b5061ffff60cc54916136a6565b61ffff92506137b9915060403d6040116137bf575b6137b1818361227c565b8101906132e0565b9161368a565b503d6137a7565b6001600160a01b038581169116141590505f61350e565b6137ff915060203d602011613805575b6137f7818361227c565b810190613267565b5f6134f7565b503d6137ed565b939750509450965060803d8111613843575b613828818361227c565b810161383391613295565b989096919591929091905f61347d565b503d61381e565b949a939991809893999d509590959c60028d1461387e575b505050509261358195926135706135899996936135819661352a565b94509450975097509394506040519363ae9e212f60e01b855260ff871660048601526080856024818b5afa978815613a7657868796889a613a38575b5061ffff6134a8816134a081613498816138d597168b6143f8565b976138eb6134cb8b6134c68c6134c68d8d6129e3565b936040516303e21fa960e61b8152602081600481875afa908115613635575f91613a19575b506001600160a01b03888116911614159081613a02575b50613934575b8080613862565b60ff6024604092839c999698959a979c5194859384926332ddf05560e11b84521660048301525afa80156136355761ffff915f916139e2575b501680156139d9576139819060cc546143f8565b8411613994579290939691945f8061392d565b60405162461bcd60e51b815260206004820152601860248201527f556e69776172546f6b656e3a2073656c6c207478206d617800000000000000006044820152606490fd5b5060cc54613981565b6139fb915060403d6040116137bf576137b1818361227c565b505f61396d565b6001600160a01b038881169116141590505f613927565b613a32915060203d602011613805576137f7818361227c565b5f613910565b939750509450965060803d8111613a6f575b613a54818361227c565b8101613a5f91613295565b989096919591929091905f6138ba565b503d613a4a565b6040513d88823e3d90fd5b634e487b7160e01b83526021600452602483fd5b9099506020813d602011613acb575b81613ab16020938361227c565b810103126102d1575160ff811681036102d157985f613430565b3d9150613aa4565b6040513d84823e3d90fd5b936001600160a01b03828116908716036134045760019450613404565b613b1591925060203d602011613805576137f7818361227c565b905f6133eb565b6128c692613c65565b6040519081526001600160a01b03841660048201529150602090829060249082905afa908115613635575f91613b5e575b505f806133b0565b613b77915060203d6020116115ec576115de818361227c565b5f613b56565b613b9791935060203d6020116115ec576115de818361227c565b915f6133a8565b60405162461bcd60e51b815260206004820152601e60248201527f556e69776172546f6b656e3a20746f20616464726573732066726f7a656e00006044820152606490fd5b613bfc915060203d6020116115ec576115de818361227c565b5f61336c565b606460405162461bcd60e51b815260206004820152602060248201527f556e69776172546f6b656e3a2066726f6d20616464726573732066726f7a656e6044820152fd5b613c5f915060203d6020116115ec576115de818361227c565b5f61333b565b6001600160a01b03908116918215613d815716918215613d30575f82815260ca602052604081205491808310613cdc57604082827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef95876020965260ca8652038282205586815220818154019055604051908152a3565b60405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608490fd5b60405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608490fd5b8115613dde570490565b634e487b7160e01b5f52601260045260245ffd5b61022b545f61022c549061022d5491613e2f61022e5493613e225f61022b555f61022c555f61022d555f61022e55565b6134c68360011c876129e3565b9260018060a01b03918260c9541690604095865197886303e21fa960e61b9485825281600460209c8d935afa9081156142b7579087918991614382575b5016613e79838230612a04565b8851613e8481612228565b6002815289368c83013730613e988261439f565b5289516315ab88c960e31b81528b81600481865afa908115614378578a9161435b575b5088613ec6836143ac565b91169052813b1561435757613f07899283928c5194858094819363791ac94760e01b83528a600484015283602484015260a0604484015260a48301906143bc565b30606483015242608483015203925af180156142b75761433c575b5090613f3a613f4992613f3f83613f3a479384612d64565b613dd4565b9460011c90612d64565b928061432c575b5080614158575b5081614021575b5050808460049260c954168551938480926361d027b360e01b82525afa918215614017578392839283928392613ff8575b504791165af1613f9d612c9c565b5015613fa7575050565b60849250519062461bcd60e51b82526004820152602560248201527f556e69776172546f6b656e3a207472656173757279207472616e736665722066604482015264185a5b195960da1b6064820152fd5b614010919250883d8a11613805576137f7818361227c565b905f613f8f565b84513d85823e3d90fd5b30845260ca86528484205490868460c9541691600488518094819382525afa90811561414e576004929185918791614131575b501692614062828530612a04565b878560c95416885194858092630189e03560e51b82525afa9283156141275791606093918695938893614107575b5060c492938951968795869463f305d71960e01b865230600487015260248601528a60448601528a60648601521660848401524260a48401525af18015614017576140dc575b80613f5e565b606090813d8111614100575b6140f2818361227c565b810103126102d1575f6140d6565b503d6140e8565b60c49350614121908b3d8d11613805576137f7818361227c565b92614090565b87513d88823e3d90fd5b6141489150893d8b11613805576137f7818361227c565b5f614054565b86513d87823e3d90fd5b8360c954169086518381528881600481865afa908115614322579086918891614305575b50169187519061418b82612228565b6002825288368b84013788516315ab88c960e31b81528a81600481885afa9081156142de5789916142e8575b50876141c28461439f565b9116905288516359e9079b60e11b81528a81600481855afa9081156142de57918b916004969594938b916142c1575b50896141fc856143ac565b911690528a5163f77c479160e01b815295869182905afa9384156142b7578894614298575b50823b15614294579161425b879289948b519687958694859363b6f9de9560e01b85528960048601526080602486015260848501906143bc565b9116604483015242606483015203925af1801561414e57908591614280575b50613f57565b614289906121e4565b610e6957835f61427a565b8780fd5b6142b09194508a3d8c11613805576137f7818361227c565b925f614221565b89513d8a823e3d90fd5b6142d89150833d8511613805576137f7818361227c565b5f6141f1565b8a513d8b823e3d90fd5b6142ff91508b3d8d11613805576137f7818361227c565b5f6141b7565b61431c91508a3d8c11613805576137f7818361227c565b5f61417c565b88513d89823e3d90fd5b6143369030612b94565b5f613f50565b613f4992919761434e613f3a926121e4565b97919250613f22565b8880fd5b61437291508c8d3d10613805576137f7818361227c565b5f613ebb565b8b513d8c823e3d90fd5b61439991508b3d8d11613805576137f7818361227c565b5f613e6c565b805115612d885760200190565b805160011015612d885760400190565b9081518082526020808093019301915f5b8281106143db575050505090565b83516001600160a01b0316855293810193928101926001016143cd565b9081158015614415575b61440f5761271091020490565b50505f90565b50801561440256fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca26469706673582212200d42d3b441f78d89b38894d4b3d79f285ec24905a6574f5b0781ebd46bfabd3164736f6c63430008150033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ 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.