More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 14 from a total of 14 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer | 50061420 | 422 days ago | IN | 0 POL | 0.00197431 | ||||
Approve | 50060889 | 422 days ago | IN | 0 POL | 0.00356116 | ||||
Transfer | 50060844 | 422 days ago | IN | 0 POL | 0.0023278 | ||||
Transfer | 50059949 | 422 days ago | IN | 0 POL | 0.00305843 | ||||
Transfer | 50058911 | 422 days ago | IN | 0 POL | 0.00713802 | ||||
Approve | 50058305 | 422 days ago | IN | 0 POL | 0.00590527 | ||||
Approve | 50058106 | 422 days ago | IN | 0 POL | 0.00644111 | ||||
Transfer | 50028778 | 423 days ago | IN | 0 POL | 0.06500615 | ||||
Transfer | 49941010 | 425 days ago | IN | 0 POL | 0.00145551 | ||||
Approve | 49896910 | 426 days ago | IN | 0 POL | 0.00756962 | ||||
Transfer | 49780807 | 429 days ago | IN | 0 POL | 0.01154663 | ||||
Approve | 46744121 | 506 days ago | IN | 0 POL | 0.00417297 | ||||
Approve | 45468435 | 538 days ago | IN | 0 POL | 0.00425292 | ||||
Approve | 45467383 | 538 days ago | IN | 0 POL | 0.00324062 |
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
42072897 | 625 days ago | Contract Creation | 0 POL |
Loading...
Loading
Contract Name:
Chamber
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
/** * SPDX-License-Identifier: Apache License 2.0 * * Copyright 2018 Set Labs Inc. * Copyright 2022 Smash Works Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * NOTICE * * This is a modified code from Set Labs Inc. found at * * https://github.com/SetProtocol/set-protocol-contracts * * All changes made by Smash Works Inc. are described and documented at * * https://docs.arch.finance/chambers * * * %@@@@@ * @@@@@@@@@@@ * #@@@@@ @@@ @@ @@ * @@@@@@ @@@ @@@@ @@ * @@@@@@ @@ @@ @@ @@@@@ @@@@@ @@@*@@ * .@@@@@ @@@ @@@@@@@@ @@ @@ @@ @@ * @@@@@( ((((( @@@ @@@ @@ @@@@@ @@ @@ * @@@@@@ ((((((( * @@@@@#((((((( * @@@@@((((( * @@@(( */ pragma solidity ^0.8.17.0; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {ERC20} from "solmate/tokens/ERC20.sol"; import {Owned} from "solmate/auth/Owned.sol"; import {ReentrancyGuard} from "solmate/utils/ReentrancyGuard.sol"; import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import {ArrayUtils} from "./lib/ArrayUtils.sol"; import {IChamberGod} from "./interfaces/IChamberGod.sol"; import {IChamber} from "./interfaces/IChamber.sol"; import {PreciseUnitMath} from "./lib/PreciseUnitMath.sol"; import {Address} from "@openzeppelin/contracts/utils/Address.sol"; contract Chamber is IChamber, Owned, ReentrancyGuard, ERC20 { /*////////////////////////////////////////////////////////////// CONSTANTS //////////////////////////////////////////////////////////////*/ IChamberGod private god; /*////////////////////////////////////////////////////////////// LIBRARIES //////////////////////////////////////////////////////////////*/ using ArrayUtils for address[]; using EnumerableSet for EnumerableSet.AddressSet; using SafeERC20 for IERC20; using Address for address; using PreciseUnitMath for uint256; /*////////////////////////////////////////////////////////////// CHAMBER STORAGE //////////////////////////////////////////////////////////////*/ address[] public constituents; mapping(address => uint256) public constituentQuantities; EnumerableSet.AddressSet private wizards; EnumerableSet.AddressSet private managers; EnumerableSet.AddressSet private allowedContracts; ChamberState private chamberLockState = ChamberState.UNLOCKED; /*////////////////////////////////////////////////////////////// MODIFIERS //////////////////////////////////////////////////////////////*/ modifier onlyManager() virtual { require(isManager(msg.sender), "Must be Manager"); _; } modifier onlyWizard() virtual { require(isWizard(msg.sender), "Must be a wizard"); _; } modifier chambersNonReentrant() virtual { require(chamberLockState == ChamberState.UNLOCKED, "Non reentrancy allowed"); chamberLockState = ChamberState.LOCKED; _; chamberLockState = ChamberState.UNLOCKED; } /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ /** * @param _owner Owner of the chamber * @param _name Name of the chamber token * @param _symbol Symbol of the chamber token * @param _constituents Initial constituents addresses of the chamber * @param _quantities Initial quantities of the chamber constituents * @param _wizards Allowed addresses that can access onlyWizard functions * @param _managers Allowed addresses that can access onlyManager functions */ constructor( address _owner, string memory _name, string memory _symbol, address[] memory _constituents, uint256[] memory _quantities, address[] memory _wizards, address[] memory _managers ) Owned(_owner) ERC20(_name, _symbol, 18) { constituents = _constituents; god = IChamberGod(msg.sender); for (uint256 i = 0; i < _wizards.length; i++) { require(wizards.add(_wizards[i]), "Cannot add wizard"); } for (uint256 i = 0; i < _managers.length; i++) { require(managers.add(_managers[i]), "Cannot add manager"); } for (uint256 j = 0; j < _constituents.length; j++) { constituentQuantities[_constituents[j]] = _quantities[j]; } } /*////////////////////////////////////////////////////////////// CHAMBER MANAGEMENT //////////////////////////////////////////////////////////////*/ /** * Allows the wizard to add a new constituent to the Chamber * * @param _constituent The address of the constituent to add */ function addConstituent(address _constituent) external onlyWizard nonReentrant { require(!isConstituent(_constituent), "Must not be constituent"); constituents.push(_constituent); emit ConstituentAdded(_constituent); } /** * Allows the wizard to remove a constituent from the Chamber * * @param _constituent The address of the constituent to remove */ function removeConstituent(address _constituent) external onlyWizard nonReentrant { require(isConstituent(_constituent), "Must be constituent"); constituents.removeStorage(_constituent); emit ConstituentRemoved(_constituent); } /** * Checks if the address is a manager of the Chamber * * @param _manager The address of a manager * * @return bool True/False if the address is a manager or not */ function isManager(address _manager) public view returns (bool) { return managers.contains(_manager); } /** * Checks if the address is a wizard of the Chamber * * @param _wizard The address of a wizard * * @return bool True/False if the address is a wizard or not */ function isWizard(address _wizard) public view returns (bool) { return wizards.contains(_wizard); } /** * Checks if the address is a constituent of the Chamber * * @param _constituent The address of a constituent * * @return bool True/False if the address is a constituent or not */ function isConstituent(address _constituent) public view returns (bool) { return constituents.contains(_constituent); } /** * Allows the Owner to add a new manager to the Chamber * * @param _manager The address of the manager to add */ function addManager(address _manager) external onlyOwner nonReentrant { require(!isManager(_manager), "Already manager"); require(_manager != address(0), "Cannot add null address"); require(managers.add(_manager), "Cannot add manager"); emit ManagerAdded(_manager); } /** * Allows the Owner to remove a manager from the Chamber * * @param _manager The address of the manager to remove */ function removeManager(address _manager) external onlyOwner nonReentrant { require(isManager(_manager), "Not a manager"); require(managers.remove(_manager), "Cannot remove manager"); emit ManagerRemoved(_manager); } /** * Allows a Manager to add a new wizard to the Chamber * * @param _wizard The address of the wizard to add */ function addWizard(address _wizard) external onlyManager nonReentrant { require(god.isWizard(_wizard), "Wizard not validated in ChamberGod"); require(!isWizard(_wizard), "Wizard already in Chamber"); require(wizards.add(_wizard), "Cannot add wizard"); emit WizardAdded(_wizard); } /** * Allows a Manager to remove a wizard from the Chamber * * @param _wizard The address of the wizard to remove */ function removeWizard(address _wizard) external onlyManager nonReentrant { require(isWizard(_wizard), "Wizard not in chamber"); require(wizards.remove(_wizard), "Cannot remove wizard"); emit WizardRemoved(_wizard); } /** * Returns an array with the addresses of all the constituents of the * Chamber * * @return an array of addresses for the constituents */ function getConstituentsAddresses() external view returns (address[] memory) { return constituents; } /** * Returns an array with the quantities of all the constituents of the * Chamber * * @return an array of uint256 for the quantities of the constituents */ function getQuantities() external view returns (uint256[] memory) { uint256[] memory quantities = new uint256[](constituents.length); for (uint256 i = 0; i < constituents.length; i++) { quantities[i] = constituentQuantities[constituents[i]]; } return quantities; } /** * Returns the quantity of a constituent of the Chamber * * @param _constituent The address of the constituent * * @return uint256 The quantity of the constituent */ function getConstituentQuantity(address _constituent) external view returns (uint256) { return constituentQuantities[_constituent]; } /** * Returns the addresses of all the wizards of the Chamber * * @return address[] Array containing the addresses of the wizards of the Chamber */ function getWizards() external view returns (address[] memory) { return wizards.values(); } /** * Returns the addresses of all the managers of the Chamber * * @return address[] Array containing the addresses of the managers of the Chamber */ function getManagers() external view returns (address[] memory) { return managers.values(); } /** * Returns the addresses of all the allowedContracts of the Chamber * * @return address[] Array containing the addresses of the allowedContracts of the Chamber */ function getAllowedContracts() external view returns (address[] memory) { return allowedContracts.values(); } /** * Allows a Manager to add a new allowedContract to the Chamber * * @param _target The address of the allowedContract to add */ function addAllowedContract(address _target) external onlyManager nonReentrant { require(god.isAllowedContract(_target), "Contract not allowed in ChamberGod"); require(!isAllowedContract(_target), "Contract already allowed"); require(allowedContracts.add(_target), "Cannot add contract"); emit AllowedContractAdded(_target); } /** * Allows a Manager to remove an allowedContract from the Chamber * * @param _target The address of the allowedContract to remove */ function removeAllowedContract(address _target) external onlyManager nonReentrant { require(isAllowedContract(_target), "Contract not allowed"); require(allowedContracts.remove(_target), "Cannot remove contract"); emit AllowedContractRemoved(_target); } /** * Checks if the address is an allowedContract of the Chamber * * @param _target The address of an allowedContract * * @return bool True/False if the address is an allowedContract or not */ function isAllowedContract(address _target) public view returns (bool) { return allowedContracts.contains(_target); } /*////////////////////////////////////////////////////////////// CHAMBER LOGIC //////////////////////////////////////////////////////////////*/ /** * Allows a wizard to mint an specific amount of chamber tokens * to a recipient * * @param _recipient The address of the recipient * @param _quantity The quantity of the chamber to mint */ function mint(address _recipient, uint256 _quantity) external onlyWizard nonReentrant { _mint(_recipient, _quantity); } /** * Allows a wizard to burn an specific amount of chamber tokens * from a source * * @param _from The address of the source to burn from * @param _quantity The quantity of the chamber tokens to burn */ function burn(address _from, uint256 _quantity) external onlyWizard nonReentrant { _burn(_from, _quantity); } /** * Locks the chamber from potentially malicious outside calls of contracts * that were not created by arch-protocol */ function lockChamber() external onlyWizard nonReentrant { require(chamberLockState == ChamberState.UNLOCKED, "Chamber locked"); chamberLockState = ChamberState.LOCKED; } /** * Unlocks the chamber from potentially malicious outside calls of contracts * that were not created by arch-protocol */ function unlockChamber() external onlyWizard nonReentrant { require(chamberLockState == ChamberState.LOCKED, "Chamber already unlocked"); chamberLockState = ChamberState.UNLOCKED; } /** * Allows a wizard to transfer an specific amount of constituent tokens * to a recipient * * @param _constituent The address of the constituent * @param _recipient The address of the recipient to transfer tokens to * @param _quantity The quantity of the constituent to transfer */ function withdrawTo(address _constituent, address _recipient, uint256 _quantity) external onlyWizard nonReentrant { if (_quantity > 0) { // Retrieve current balance of token for the vault uint256 existingVaultBalance = IERC20(_constituent).balanceOf(address(this)); // Call specified ERC20 token contract to transfer tokens from Vault to user IERC20(_constituent).safeTransfer(_recipient, _quantity); // Verify transfer quantity is reflected in balance uint256 newVaultBalance = IERC20(_constituent).balanceOf(address(this)); // Check to make sure current balances are as expected require( newVaultBalance >= existingVaultBalance - _quantity, "Chamber.withdrawTo: Invalid post-withdraw balance" ); } } /** * Update the quantities of the constituents in the chamber based on the * total suppply of tokens. Only considers constituents in the constituents * list. Used by wizards. E.g. after an uncollateralized mint in the streaming fee wizard . * */ function updateQuantities() external onlyWizard nonReentrant chambersNonReentrant { for (uint256 i = 0; i < constituents.length; i++) { address _constituent = constituents[i]; uint256 currentBalance = IERC20(_constituent).balanceOf(address(this)); uint256 _newQuantity = currentBalance.preciseDiv(totalSupply, decimals); require(_newQuantity > 0, "Zero quantity not allowed"); constituentQuantities[_constituent] = _newQuantity; } } /** * Allows wizards to make low level calls to contracts that have been * added to the allowedContracts mapping. * * @param _sellToken The address of the token to sell * @param _sellQuantity The amount of sellToken to sell * @param _buyToken The address of the token to buy * @param _minBuyQuantity The minimum amount of buyToken that should be bought * @param _data The data to be passed to the contract * @param _target The address of the contract to call * @param _allowanceTarget The address of the contract to give allowance of tokens * * @return tokenAmountBought The amount of buyToken bought */ function executeTrade( address _sellToken, uint256 _sellQuantity, address _buyToken, uint256 _minBuyQuantity, bytes memory _data, address payable _target, address _allowanceTarget ) external onlyWizard nonReentrant returns (uint256 tokenAmountBought) { require(_target != address(this), "Cannot invoke the Chamber"); require(isAllowedContract(_target), "Target not allowed"); uint256 tokenAmountBefore = IERC20(_buyToken).balanceOf(address(this)); uint256 currentAllowance = IERC20(_sellToken).allowance(address(this), _allowanceTarget); if (currentAllowance < _sellQuantity) { IERC20(_sellToken).safeIncreaseAllowance( _allowanceTarget, (_sellQuantity - currentAllowance) ); } _invokeContract(_data, _target); currentAllowance = IERC20(_sellToken).allowance(address(this), _allowanceTarget); IERC20(_sellToken).safeDecreaseAllowance(_allowanceTarget, currentAllowance); uint256 tokenAmountAfter = IERC20(_buyToken).balanceOf(address(this)); tokenAmountBought = tokenAmountAfter - tokenAmountBefore; require(tokenAmountBought >= _minBuyQuantity, "Underbought buy quantity"); return tokenAmountBought; } /** * Low level call to a contract. Only allowed contracts can be called. * * @param _data The encoded calldata to be passed to the contract * @param _target The address of the contract to call * * @return response The response bytes from the contract call */ function _invokeContract(bytes memory _data, address payable _target) internal returns (bytes memory response) { response = address(_target).functionCall(_data); require(response.length > 0, "Low level functionCall failed"); return (response); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol) /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. abstract contract ERC20 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount); /*////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ string public name; string public symbol; uint8 public immutable decimals; /*////////////////////////////////////////////////////////////// ERC20 STORAGE //////////////////////////////////////////////////////////////*/ uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; /*////////////////////////////////////////////////////////////// EIP-2612 STORAGE //////////////////////////////////////////////////////////////*/ uint256 internal immutable INITIAL_CHAIN_ID; bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; mapping(address => uint256) public nonces; /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( string memory _name, string memory _symbol, uint8 _decimals ) { name = _name; symbol = _symbol; decimals = _decimals; INITIAL_CHAIN_ID = block.chainid; INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); } /*////////////////////////////////////////////////////////////// ERC20 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 amount) public virtual returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function transfer(address to, uint256 amount) public virtual returns (bool) { balanceOf[msg.sender] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(msg.sender, to, amount); return true; } function transferFrom( address from, address to, uint256 amount ) public virtual returns (bool) { uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; balanceOf[from] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(from, to, amount); return true; } /*////////////////////////////////////////////////////////////// EIP-2612 LOGIC //////////////////////////////////////////////////////////////*/ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); // Unchecked because the only math done is incrementing // the owner's nonce which cannot realistically overflow. unchecked { address recoveredAddress = ecrecover( keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256( abi.encode( keccak256( "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" ), owner, spender, value, nonces[owner]++, deadline ) ) ) ), v, r, s ); require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER"); allowance[recoveredAddress][spender] = value; } emit Approval(owner, spender, value); } function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256("1"), block.chainid, address(this) ) ); } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 amount) internal virtual { totalSupply += amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(address(0), to, amount); } function _burn(address from, uint256 amount) internal virtual { balanceOf[from] -= amount; // Cannot underflow because a user's balance // will never be larger than the total supply. unchecked { totalSupply -= amount; } emit Transfer(from, address(0), amount); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Simple single owner authorization mixin. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol) abstract contract Owned { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event OwnershipTransferred(address indexed user, address indexed newOwner); /*////////////////////////////////////////////////////////////// OWNERSHIP STORAGE //////////////////////////////////////////////////////////////*/ address public owner; modifier onlyOwner() virtual { require(msg.sender == owner, "UNAUTHORIZED"); _; } /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor(address _owner) { owner = _owner; emit OwnershipTransferred(address(0), _owner); } /*////////////////////////////////////////////////////////////// OWNERSHIP LOGIC //////////////////////////////////////////////////////////////*/ function transferOwnership(address newOwner) public virtual onlyOwner { owner = newOwner; emit OwnershipTransferred(msg.sender, newOwner); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Gas optimized reentrancy protection for smart contracts. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ReentrancyGuard.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol) abstract contract ReentrancyGuard { uint256 private locked = 1; modifier nonReentrant() virtual { require(locked == 1, "REENTRANCY"); locked = 2; _; locked = 1; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values in the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
/** * SPDX-License-Identifier: Apache License 2.0 * * Copyright 2018 Set Labs Inc. * Copyright 2022 Smash Works Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * NOTICE * * This is a modified code from Set Labs Inc. found at * * https://github.com/SetProtocol/set-protocol-contracts * * All changes made by Smash Works Inc. are described and documented at * * https://docs.arch.finance/chambers * * * %@@@@@ * @@@@@@@@@@@ * #@@@@@ @@@ @@ @@ * @@@@@@ @@@ @@@@ @@ * @@@@@@ @@ @@ @@ @@@@@ @@@@@ @@@*@@ * .@@@@@ @@@ @@@@@@@@ @@ @@ @@ @@ * @@@@@( ((((( @@@ @@@ @@ @@@@@ @@ @@ * @@@@@@ ((((((( * @@@@@#((((((( * @@@@@((((( * @@@(( */ pragma solidity ^0.8.17.0; library ArrayUtils { /** * Returns the index of the element 'a' in the _array provided. It also returns true if * the element was found, and false if not, as -1 is not a possible output. * * @param _array Array to check * @param a Element to check in array * * @return A tuple with the index of the element, and a bool */ function indexOf(address[] memory _array, address a) internal pure returns (uint256, bool) { uint256 length = _array.length; for (uint256 i = 0; i < length; i++) { if (_array[i] == a) { return (i, true); } } return (0, false); } /** * Returns true if the element 'a' is in the _array provided, and false otherwise. * * @param _array Array to check * @param a Element to check in array * * @return True if the element is present in the array */ function contains(address[] memory _array, address a) internal pure returns (bool) { (, bool isIn) = indexOf(_array, a); return isIn; } /** * Returns true if the _array contains duplicates, and false otherwise. * * @param _array Array to check * * @return True if there are duplicates in the array */ function hasDuplicate(address[] memory _array) internal pure returns (bool) { require(_array.length > 0, "_array is empty"); for (uint256 i = 0; i < _array.length - 1; i++) { address current = _array[i]; for (uint256 j = i + 1; j < _array.length; j++) { if (current == _array[j]) { return true; } } } return false; } /** * Removes the element 'a' from the memory _array if present. Will revert if the * element is not present. Returns a new array. * * @param _array Array to check * @param a Element to remove * * @return A new array without the element */ function remove(address[] memory _array, address a) internal pure returns (address[] memory) { (uint256 index, bool isIn) = indexOf(_array, a); if (!isIn) { revert("Address not in array"); } else { (address[] memory _newArray,) = pop(_array, index); return _newArray; } } /** * Removes the element 'a' from the storage _array if present. Will revert if the * element is not present. Moves the last element in the _array to the index in * which the element 'a' is present. Changes the array in-place. * * @param _array Array to modify * @param a Element to remove */ function removeStorage(address[] storage _array, address a) internal { (uint256 index, bool isIn) = indexOf(_array, a); if (!isIn) { revert("Address not in array"); } else { uint256 lastIndex = _array.length - 1; // If the array would be empty, the previous line would throw, so no underflow here if (index != lastIndex) _array[index] = _array[lastIndex]; _array.pop(); } } /** * Removes from the array the element in the index specified. Returns a new array and * the element removed, as a tuple. * * @param _array Array to modify * @param index Index of element to remove * * @return New array amd the removed element, as a tuple */ function pop(address[] memory _array, uint256 index) internal pure returns (address[] memory, address) { uint256 length = _array.length; require(index < _array.length, "Index must be < _array length"); address[] memory newAddresses = new address[](length - 1); for (uint256 i = 0; i < index; i++) { newAddresses[i] = _array[i]; } for (uint256 j = index + 1; j < length; j++) { newAddresses[j - 1] = _array[j]; } return (newAddresses, _array[index]); } }
/** * SPDX-License-Identifier: Apache License 2.0 * * Copyright 2018 Set Labs Inc. * Copyright 2022 Smash Works Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * NOTICE * * This is a modified code from Set Labs Inc. found at * * https://github.com/SetProtocol/set-protocol-contracts * * All changes made by Smash Works Inc. are described and documented at * * https://docs.arch.finance/chambers * * * %@@@@@ * @@@@@@@@@@@ * #@@@@@ @@@ @@ @@ * @@@@@@ @@@ @@@@ @@ * @@@@@@ @@ @@ @@ @@@@@ @@@@@ @@@*@@ * .@@@@@ @@@ @@@@@@@@ @@ @@ @@ @@ * @@@@@( ((((( @@@ @@@ @@ @@@@@ @@ @@ * @@@@@@ ((((((( * @@@@@#((((((( * @@@@@((((( * @@@(( */ pragma solidity ^0.8.17.0; interface IChamberGod { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event ChamberCreated(address indexed _chamber, address _owner, string _name, string _symbol); event WizardAdded(address indexed _wizard); event WizardRemoved(address indexed _wizard); event AllowedContractAdded(address indexed _allowedContract); event AllowedContractRemoved(address indexed _allowedContract); /*////////////////////////////////////////////////////////////// CHAMBER GOD LOGIC //////////////////////////////////////////////////////////////*/ function createChamber( string memory _name, string memory _symbol, address[] memory _constituents, uint256[] memory _quantities, address[] memory _wizards, address[] memory _managers ) external returns (address); function getWizards() external view returns (address[] memory); function getChambers() external view returns (address[] memory); function isWizard(address _wizard) external view returns (bool); function isChamber(address _chamber) external view returns (bool); function addWizard(address _wizard) external; function removeWizard(address _wizard) external; function getAllowedContracts() external view returns (address[] memory); function addAllowedContract(address _target) external; function removeAllowedContract(address _target) external; function isAllowedContract(address _target) external view returns (bool); }
/** * SPDX-License-Identifier: Apache License 2.0 * * Copyright 2018 Set Labs Inc. * Copyright 2022 Smash Works Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * NOTICE * * This is a modified code from Set Labs Inc. found at * * https://github.com/SetProtocol/set-protocol-contracts * * All changes made by Smash Works Inc. are described and documented at * * https://docs.arch.finance/chambers * * * %@@@@@ * @@@@@@@@@@@ * #@@@@@ @@@ @@ @@ * @@@@@@ @@@ @@@@ @@ * @@@@@@ @@ @@ @@ @@@@@ @@@@@ @@@*@@ * .@@@@@ @@@ @@@@@@@@ @@ @@ @@ @@ * @@@@@( ((((( @@@ @@@ @@ @@@@@ @@ @@ * @@@@@@ ((((((( * @@@@@#((((((( * @@@@@((((( * @@@(( */ pragma solidity ^0.8.17.0; interface IChamber { /*////////////////////////////////////////////////////////////// ENUMS //////////////////////////////////////////////////////////////*/ enum ChamberState { LOCKED, UNLOCKED } /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event ManagerAdded(address indexed _manager); event ManagerRemoved(address indexed _manager); event ConstituentAdded(address indexed _constituent); event ConstituentRemoved(address indexed _constituent); event WizardAdded(address indexed _wizard); event WizardRemoved(address indexed _wizard); event AllowedContractAdded(address indexed _allowedContract); event AllowedContractRemoved(address indexed _allowedContract); /*////////////////////////////////////////////////////////////// CHAMBER MANAGEMENT //////////////////////////////////////////////////////////////*/ function addConstituent(address _constituent) external; function removeConstituent(address _constituent) external; function isManager(address _manager) external view returns (bool); function isWizard(address _wizard) external view returns (bool); function isConstituent(address _constituent) external view returns (bool); function addManager(address _manager) external; function removeManager(address _manager) external; function addWizard(address _wizard) external; function removeWizard(address _wizard) external; function getConstituentsAddresses() external view returns (address[] memory); function getQuantities() external view returns (uint256[] memory); function getConstituentQuantity(address _constituent) external view returns (uint256); function getWizards() external view returns (address[] memory); function getManagers() external view returns (address[] memory); function getAllowedContracts() external view returns (address[] memory); function mint(address _recipient, uint256 _quantity) external; function burn(address _from, uint256 _quantity) external; function withdrawTo(address _constituent, address _recipient, uint256 _quantity) external; function updateQuantities() external; function lockChamber() external; function unlockChamber() external; function addAllowedContract(address target) external; function removeAllowedContract(address target) external; function isAllowedContract(address _target) external returns (bool); function executeTrade( address _sellToken, uint256 _sellQuantity, address _buyToken, uint256 _minBuyQuantity, bytes memory _data, address payable _target, address _allowanceTarget ) external returns (uint256 tokenAmountBought); }
/** * SPDX-License-Identifier: Apache License 2.0 * * Copyright 2018 Set Labs Inc. * Copyright 2022 Smash Works Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * NOTICE * * This is a modified code from Set Labs Inc. found at * * https://github.com/SetProtocol/set-protocol-contracts * * All changes made by Smash Works Inc. are described and documented at * * https://docs.arch.finance/chambers * * * %@@@@@ * @@@@@@@@@@@ * #@@@@@ @@@ @@ @@ * @@@@@@ @@@ @@@@ @@ * @@@@@@ @@ @@ @@ @@@@@ @@@@@ @@@*@@ * .@@@@@ @@@ @@@@@@@@ @@ @@ @@ @@ * @@@@@( ((((( @@@ @@@ @@ @@@@@ @@ @@ * @@@@@@ ((((((( * @@@@@#((((((( * @@@@@((((( * @@@(( */ pragma solidity ^0.8.17.0; library PreciseUnitMath { /** * Multiplies value _a by value _b (result is rounded down). It's assumed that the value _b is the significand * of a number with _deicmals precision, so the result of the multiplication will be divided by [10e_decimals]. * The result can be interpreted as [wei]. * * @param _a Unsigned integer [wei] * @param _b Unsigned integer [10e_decimals] * @param _decimals Decimals of _b */ function preciseMul(uint256 _a, uint256 _b, uint256 _decimals) internal pure returns (uint256) { uint256 preciseUnit = 10 ** _decimals; return (_a * _b) / preciseUnit; } /** * Multiplies value _a by value _b (result is rounded up). It's assumed that the value _b is the significand * of a number with _decimals precision, so the result of the multiplication will be divided by [10e_decimals]. * The result will never reach zero. The result can be interpreted as [wei]. * * @param _a Unsigned integer [wei] * @param _b Unsigned integer [10e_decimals] * @param _decimals Decimals of _b */ function preciseMulCeil(uint256 _a, uint256 _b, uint256 _decimals) internal pure returns (uint256) { if (_a == 0 || _b == 0) { return 0; } uint256 preciseUnit = 10 ** _decimals; return (((_a * _b) - 1) / preciseUnit) + 1; } /** * Divides value _a by value _b (result is rounded down). Value _a is scaled up to match value _b decimals. * The result can be interpreted as [wei]. * * @param _a Unsigned integer [wei] * @param _b Unsigned integer [10e_decimals] * @param _decimals Decimals of _b */ function preciseDiv(uint256 _a, uint256 _b, uint256 _decimals) internal pure returns (uint256) { require(_b != 0, "Cannot divide by 0"); uint256 preciseUnit = 10 ** _decimals; return (_a * preciseUnit) / _b; } /** * Divides value _a by value _b (result is rounded up or away from 0). Value _a is scaled up to match * value _b decimals. The result will never be zero, except when _a is zero. The result can be interpreted * as [wei]. * * @param _a Unsigned integer [wei] * @param _b Unsigned integer [10e_decimals] * @param _decimals Decimals of _b */ function preciseDivCeil(uint256 _a, uint256 _b, uint256 _decimals) internal pure returns (uint256) { require(_b != 0, "Cannot divide by 0"); uint256 preciseUnit = 10 ** _decimals; return _a > 0 ? ((((_a * preciseUnit) - 1) / _b) + 1) : 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * 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.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (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 IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
{ "remappings": [ "@openzeppelin/=lib/openzeppelin-contracts/", "ds-test/=lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "solmate/=lib/solmate/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address[]","name":"_constituents","type":"address[]"},{"internalType":"uint256[]","name":"_quantities","type":"uint256[]"},{"internalType":"address[]","name":"_wizards","type":"address[]"},{"internalType":"address[]","name":"_managers","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_allowedContract","type":"address"}],"name":"AllowedContractAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_allowedContract","type":"address"}],"name":"AllowedContractRemoved","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":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_constituent","type":"address"}],"name":"ConstituentAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_constituent","type":"address"}],"name":"ConstituentRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_manager","type":"address"}],"name":"ManagerAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_manager","type":"address"}],"name":"ManagerRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","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":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_wizard","type":"address"}],"name":"WizardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_wizard","type":"address"}],"name":"WizardRemoved","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_target","type":"address"}],"name":"addAllowedContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_constituent","type":"address"}],"name":"addConstituent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_manager","type":"address"}],"name":"addManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wizard","type":"address"}],"name":"addWizard","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","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":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"constituentQuantities","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"constituents","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_sellToken","type":"address"},{"internalType":"uint256","name":"_sellQuantity","type":"uint256"},{"internalType":"address","name":"_buyToken","type":"address"},{"internalType":"uint256","name":"_minBuyQuantity","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"address payable","name":"_target","type":"address"},{"internalType":"address","name":"_allowanceTarget","type":"address"}],"name":"executeTrade","outputs":[{"internalType":"uint256","name":"tokenAmountBought","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAllowedContracts","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_constituent","type":"address"}],"name":"getConstituentQuantity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConstituentsAddresses","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getManagers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getQuantities","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWizards","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_target","type":"address"}],"name":"isAllowedContract","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_constituent","type":"address"}],"name":"isConstituent","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_manager","type":"address"}],"name":"isManager","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wizard","type":"address"}],"name":"isWizard","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockChamber","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","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":[{"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":[{"internalType":"address","name":"_target","type":"address"}],"name":"removeAllowedContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_constituent","type":"address"}],"name":"removeConstituent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_manager","type":"address"}],"name":"removeManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wizard","type":"address"}],"name":"removeWizard","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"unlockChamber","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateQuantities","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_constituent","type":"address"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"withdrawTo","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60e060405260018080556011805460ff191690911790553480156200002357600080fd5b5060405162003d7338038062003d7383398101604081905262000046916200064d565b600080546001600160a01b0319166001600160a01b0389169081178255604051889288926012928c92907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506002620000a48482620007f8565b506003620000b38382620007f8565b5060ff81166080524660a052620000c9620002c7565b60c05250508451620000e491506009906020870190620003d5565b50600880546001600160a01b0319163317905560005b825181101562000196576200013b8382815181106200011d576200011d620008c4565b6020026020010151600b6200036360201b620021711790919060201c565b620001815760405162461bcd60e51b815260206004820152601160248201527010d85b9b9bdd08185919081dda5e985c99607a1b60448201526064015b60405180910390fd5b806200018d81620008da565b915050620000fa565b5060005b81518110156200023357620001db828281518110620001bd57620001bd620008c4565b6020026020010151600d6200036360201b620021711790919060201c565b6200021e5760405162461bcd60e51b815260206004820152601260248201527121b0b73737ba1030b2321036b0b730b3b2b960711b604482015260640162000178565b806200022a81620008da565b9150506200019a565b5060005b8451811015620002b957838181518110620002565762000256620008c4565b6020026020010151600a6000878481518110620002775762000277620008c4565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055508080620002b090620008da565b91505062000237565b505050505050505062000980565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6002604051620002fb919062000902565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b60006200037a836001600160a01b03841662000383565b90505b92915050565b6000818152600183016020526040812054620003cc575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200037d565b5060006200037d565b8280548282559060005260206000209081019282156200042d579160200282015b828111156200042d57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620003f6565b506200043b9291506200043f565b5090565b5b808211156200043b576000815560010162000440565b80516001600160a01b03811681146200046e57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620004b457620004b462000473565b604052919050565b600082601f830112620004ce57600080fd5b81516001600160401b03811115620004ea57620004ea62000473565b602062000500601f8301601f1916820162000489565b82815285828487010111156200051557600080fd5b60005b838110156200053557858101830151828201840152820162000518565b506000928101909101919091529392505050565b60006001600160401b0382111562000565576200056562000473565b5060051b60200190565b600082601f8301126200058157600080fd5b815160206200059a620005948362000549565b62000489565b82815260059290921b84018101918181019086841115620005ba57600080fd5b8286015b84811015620005e057620005d28162000456565b8352918301918301620005be565b509695505050505050565b600082601f830112620005fd57600080fd5b8151602062000610620005948362000549565b82815260059290921b840181019181810190868411156200063057600080fd5b8286015b84811015620005e0578051835291830191830162000634565b600080600080600080600060e0888a0312156200066957600080fd5b620006748862000456565b60208901519097506001600160401b03808211156200069257600080fd5b620006a08b838c01620004bc565b975060408a0151915080821115620006b757600080fd5b620006c58b838c01620004bc565b965060608a0151915080821115620006dc57600080fd5b620006ea8b838c016200056f565b955060808a01519150808211156200070157600080fd5b6200070f8b838c01620005eb565b945060a08a01519150808211156200072657600080fd5b620007348b838c016200056f565b935060c08a01519150808211156200074b57600080fd5b506200075a8a828b016200056f565b91505092959891949750929550565b600181811c908216806200077e57607f821691505b6020821081036200079f57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620007f357600081815260208120601f850160051c81016020861015620007ce5750805b601f850160051c820191505b81811015620007ef57828155600101620007da565b5050505b505050565b81516001600160401b0381111562000814576200081462000473565b6200082c8162000825845462000769565b84620007a5565b602080601f8311600181146200086457600084156200084b5750858301515b600019600386901b1c1916600185901b178555620007ef565b600085815260208120601f198616915b82811015620008955788860151825594840194600190910190840162000874565b5085821015620008b45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b600060018201620008fb57634e487b7160e01b600052601160045260246000fd5b5060010190565b6000808354620009128162000769565b600182811680156200092d5760018114620009435762000974565b60ff198416875282151583028701945062000974565b8760005260208060002060005b858110156200096b5781548a82015290840190820162000950565b50505082870194505b50929695505050505050565b60805160a05160c0516133bc620009b76000396000610ec701526000610e920152600081816103470152611dd601526133bc6000f3fe608060405234801561001057600080fd5b50600436106102535760003560e01c8063792b1ed911610146578063a9059cbb116100c3578063d36fc0ff11610087578063d36fc0ff14610544578063d505accf1461054c578063dd62ed3e1461055f578063f2fde38b1461058a578063f3ae24151461059d578063f43b8555146105b057600080fd5b8063a9059cbb146104f0578063ac18de4314610503578063b94473ea14610516578063c3b35a7e1461051e578063c8f4feea1461053157600080fd5b806395d89b411161010a57806395d89b41146104a75780639800fc16146104af5780639908c590146104c25780639dc29fac146104d5578063a8d088bb146104e857600080fd5b8063792b1ed9146104215780637df21519146104365780637ecebe00146104615780638da5cb5b1461048157806395ad97fd1461049457600080fd5b8063313ce567116101d45780634199459f116101985780634199459f146103b1578063538741c5146103d1578063585faa2d146103e65780636a76d37b146103ee57806370a082311461040157600080fd5b8063313ce56714610342578063315749fb1461037b5780633644e5151461038357806337c1fe541461038b57806340c10f191461039e57600080fd5b806323b872dd1161021b57806323b872dd146102ee57806324aa15d7146103015780632a286cdf146103095780632c56462f1461031c5780632d06177a1461032f57600080fd5b806306fdde0314610258578063095ea7b314610276578063129928091461029957806312ab980b146102d057806318160ddd146102e5575b600080fd5b6102606105c3565b60405161026d9190612c8b565b60405180910390f35b610289610284366004612ce6565b610651565b604051901515815260200161026d565b6102c26102a7366004612d12565b6001600160a01b03166000908152600a602052604090205490565b60405190815260200161026d565b6102e36102de366004612d12565b6106be565b005b6102c260045481565b6102896102fc366004612d2f565b6107e9565b6102e36108c9565b6102e3610317366004612d12565b610995565b6102e361032a366004612d12565b610a72565b6102e361033d366004612d12565b610c61565b6103697f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff909116815260200161026d565b6102e3610dd7565b6102c2610e8e565b6102e3610399366004612d12565b610ee9565b6102e36103ac366004612ce6565b611007565b6102c26103bf366004612d12565b600a6020526000908152604090205481565b6103d9611065565b60405161026d9190612d70565b6103d9611071565b6102896103fc366004612d12565b6110d3565b6102c261040f366004612d12565b60056020526000908152604090205481565b610429611142565b60405161026d9190612dbd565b610449610444366004612df5565b61120f565b6040516001600160a01b03909116815260200161026d565b6102c261046f366004612d12565b60076020526000908152604090205481565b600054610449906001600160a01b031681565b6102896104a2366004612d12565b611239565b610260611246565b6102e36104bd366004612d12565b611253565b6102e36104d0366004612d12565b611376565b6102e36104e3366004612ce6565b611563565b6103d96115b9565b6102896104fe366004612ce6565b6115c5565b6102e3610511366004612d12565b61162b565b6103d961174b565b6102e361052c366004612d2f565b611757565b6102c261053f366004612e24565b611916565b6102e3611c7c565b6102e361055a366004612f2f565b611e9e565b6102c261056d366004612fa6565b600660209081526000928352604080842090915290825290205481565b6102e3610598366004612d12565b6120e2565b6102896105ab366004612d12565b612157565b6102896105be366004612d12565b612164565b600280546105d090612fdf565b80601f01602080910402602001604051908101604052809291908181526020018280546105fc90612fdf565b80156106495780601f1061061e57610100808354040283529160200191610649565b820191906000526020600020905b81548152906001019060200180831161062c57829003601f168201915b505050505081565b3360008181526006602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106ac9086815260200190565b60405180910390a35060015b92915050565b6106c733612157565b6106ec5760405162461bcd60e51b81526004016106e390613013565b60405180910390fd5b60015460011461070e5760405162461bcd60e51b81526004016106e39061303c565b600260015561071c81611239565b6107605760405162461bcd60e51b81526020600482015260156024820152742bb4bd30b932103737ba1034b71031b430b6b132b960591b60448201526064016106e3565b61076b600b8261218d565b6107ae5760405162461bcd60e51b815260206004820152601460248201527310d85b9b9bdd081c995b5bdd99481dda5e985c9960621b60448201526064016106e3565b6040516001600160a01b038216907f35014a11db7bdb4adb31405c5c7646a3a45bb66c22b5528b37645f2bcb88bea990600090a25060018055565b6001600160a01b03831660009081526006602090815260408083203384529091528120546000198114610845576108208382613076565b6001600160a01b03861660009081526006602090815260408083203384529091529020555b6001600160a01b0385166000908152600560205260408120805485929061086d908490613076565b90915550506001600160a01b0380851660008181526005602052604090819020805487019055519091871690600080516020613367833981519152906108b69087815260200190565b60405180910390a3506001949350505050565b6108d233611239565b6108ee5760405162461bcd60e51b81526004016106e390613089565b6001546001146109105760405162461bcd60e51b81526004016106e39061303c565b6002600155600060115460ff16600181111561092e5761092e6130b3565b1461097b5760405162461bcd60e51b815260206004820152601860248201527f4368616d62657220616c726561647920756e6c6f636b6564000000000000000060448201526064016106e3565b601180546001919060ff191682805b021790555060018055565b61099e33611239565b6109ba5760405162461bcd60e51b81526004016106e390613089565b6001546001146109dc5760405162461bcd60e51b81526004016106e39061303c565b60026001556109ea816110d3565b610a2c5760405162461bcd60e51b8152602060048201526013602482015272135d5cdd0818994818dbdb9cdd1a5d1d595b9d606a1b60448201526064016106e3565b610a376009826121a2565b6040516001600160a01b038216907f7146b276c069596d9ba13f415f0815827f3f72bc58a5e7456f2f375535cd21f390600090a25060018055565b610a7b33612157565b610a975760405162461bcd60e51b81526004016106e390613013565b600154600114610ab95760405162461bcd60e51b81526004016106e39061303c565b600260015560085460405163f43b855560e01b81526001600160a01b0383811660048301529091169063f43b855590602401602060405180830381865afa158015610b08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2c91906130c9565b610b835760405162461bcd60e51b815260206004820152602260248201527f436f6e7472616374206e6f7420616c6c6f77656420696e204368616d626572476044820152611bd960f21b60648201526084016106e3565b610b8c81612164565b15610bd95760405162461bcd60e51b815260206004820152601860248201527f436f6e747261637420616c726561647920616c6c6f776564000000000000000060448201526064016106e3565b610be4600f82612171565b610c265760405162461bcd60e51b815260206004820152601360248201527210d85b9b9bdd081859190818dbdb9d1c9858dd606a1b60448201526064016106e3565b6040516001600160a01b038216907f745213c0a7dcd996a1ded5a6943d545aadcdb27ec72b0ec5636da2a8f59fccdd90600090a25060018055565b6000546001600160a01b03163314610c8b5760405162461bcd60e51b81526004016106e3906130eb565b600154600114610cad5760405162461bcd60e51b81526004016106e39061303c565b6002600155610cbb81612157565b15610cfa5760405162461bcd60e51b815260206004820152600f60248201526e20b63932b0b23c9036b0b730b3b2b960891b60448201526064016106e3565b6001600160a01b038116610d505760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f7420616464206e756c6c206164647265737300000000000000000060448201526064016106e3565b610d5b600d82612171565b610d9c5760405162461bcd60e51b815260206004820152601260248201527121b0b73737ba1030b2321036b0b730b3b2b960711b60448201526064016106e3565b6040516001600160a01b038216907f3b4a40cccf2058c593542587329dd385be4f0b588db5471fbd9598e56dd7093a90600090a25060018055565b610de033611239565b610dfc5760405162461bcd60e51b81526004016106e390613089565b600154600114610e1e5760405162461bcd60e51b81526004016106e39061303c565b6002600190815560115460ff166001811115610e3c57610e3c6130b3565b14610e7a5760405162461bcd60e51b815260206004820152600e60248201526d10da185b58995c881b1bd8dad95960921b60448201526064016106e3565b601180546000919060ff191660018361098a565b60007f00000000000000000000000000000000000000000000000000000000000000004614610ec457610ebf612315565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b610ef233611239565b610f0e5760405162461bcd60e51b81526004016106e390613089565b600154600114610f305760405162461bcd60e51b81526004016106e39061303c565b6002600155610f3e816110d3565b15610f8b5760405162461bcd60e51b815260206004820152601760248201527f4d757374206e6f7420626520636f6e7374697475656e7400000000000000000060448201526064016106e3565b6009805460018101825560009182527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0180546001600160a01b0319166001600160a01b03841690811790915560405190917f8f63ff8fbc244d116babb3955e18cd1c02d0e8ab77369224288d679f938f81b791a25060018055565b61101033611239565b61102c5760405162461bcd60e51b81526004016106e390613089565b60015460011461104e5760405162461bcd60e51b81526004016106e39061303c565b600260015561105d82826123af565b505060018055565b6060610ebf600f612409565b606060098054806020026020016040519081016040528092919081815260200182805480156110c957602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116110ab575b5050505050905090565b60006106b882600980548060200260200160405190810160405280929190818152602001828054801561112f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611111575b505050505061241690919063ffffffff16565b60095460609060009067ffffffffffffffff81111561116357611163612e0e565b60405190808252806020026020018201604052801561118c578160200160208202803683370190505b50905060005b60095481101561120957600a6000600983815481106111b3576111b3613111565b60009182526020808320909101546001600160a01b0316835282019290925260400190205482518390839081106111ec576111ec613111565b60209081029190910101528061120181613127565b915050611192565b50919050565b6009818154811061121f57600080fd5b6000918252602090912001546001600160a01b0316905081565b60006106b8600b8361242c565b600380546105d090612fdf565b61125c33612157565b6112785760405162461bcd60e51b81526004016106e390613013565b60015460011461129a5760405162461bcd60e51b81526004016106e39061303c565b60026001556112a881612164565b6112eb5760405162461bcd60e51b815260206004820152601460248201527310dbdb9d1c9858dd081b9bdd08185b1b1bddd95960621b60448201526064016106e3565b6112f6600f8261218d565b61133b5760405162461bcd60e51b815260206004820152601660248201527510d85b9b9bdd081c995b5bdd994818dbdb9d1c9858dd60521b60448201526064016106e3565b6040516001600160a01b038216907fac2e940b68b32bc719742a99f71a86e3854dac1225e4b3de2ec392bb9850f41390600090a25060018055565b61137f33612157565b61139b5760405162461bcd60e51b81526004016106e390613013565b6001546001146113bd5760405162461bcd60e51b81526004016106e39061303c565b60026001556008546040516395ad97fd60e01b81526001600160a01b038381166004830152909116906395ad97fd90602401602060405180830381865afa15801561140c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143091906130c9565b6114875760405162461bcd60e51b815260206004820152602260248201527f57697a617264206e6f742076616c69646174656420696e204368616d626572476044820152611bd960f21b60648201526084016106e3565b61149081611239565b156114dd5760405162461bcd60e51b815260206004820152601960248201527f57697a61726420616c726561647920696e204368616d6265720000000000000060448201526064016106e3565b6114e8600b82612171565b6115285760405162461bcd60e51b815260206004820152601160248201527010d85b9b9bdd08185919081dda5e985c99607a1b60448201526064016106e3565b6040516001600160a01b038216907f18c8a5c5e19d4382b64a94b578eb09f7d1797ee3df236dba16efc12bf853bcb590600090a25060018055565b61156c33611239565b6115885760405162461bcd60e51b81526004016106e390613089565b6001546001146115aa5760405162461bcd60e51b81526004016106e39061303c565b600260015561105d828261244e565b6060610ebf600d612409565b336000908152600560205260408120805483919083906115e6908490613076565b90915550506001600160a01b03831660008181526005602052604090819020805485019055513390600080516020613367833981519152906106ac9086815260200190565b6000546001600160a01b031633146116555760405162461bcd60e51b81526004016106e3906130eb565b6001546001146116775760405162461bcd60e51b81526004016106e39061303c565b600260015561168581612157565b6116c15760405162461bcd60e51b815260206004820152600d60248201526c2737ba10309036b0b730b3b2b960991b60448201526064016106e3565b6116cc600d8261218d565b6117105760405162461bcd60e51b815260206004820152601560248201527421b0b73737ba103932b6b7bb329036b0b730b3b2b960591b60448201526064016106e3565b6040516001600160a01b038216907fef69f7d97228658c92417be1b16b19058315de71fecb435d07b7d23728b6bd3190600090a25060018055565b6060610ebf600b612409565b61176033611239565b61177c5760405162461bcd60e51b81526004016106e390613089565b60015460011461179e5760405162461bcd60e51b81526004016106e39061303c565b6002600155801561190d576040516370a0823160e01b81523060048201526000906001600160a01b038516906370a0823190602401602060405180830381865afa1580156117f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118149190613140565b905061182a6001600160a01b03851684846124b0565b6040516370a0823160e01b81523060048201526000906001600160a01b038616906370a0823190602401602060405180830381865afa158015611871573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118959190613140565b90506118a18383613076565b81101561190a5760405162461bcd60e51b815260206004820152603160248201527f4368616d6265722e7769746864726177546f3a20496e76616c696420706f73746044820152702d77697468647261772062616c616e636560781b60648201526084016106e3565b50505b50506001805550565b600061192133611239565b61193d5760405162461bcd60e51b81526004016106e390613089565b60015460011461195f5760405162461bcd60e51b81526004016106e39061303c565b6002600155306001600160a01b038416036119bc5760405162461bcd60e51b815260206004820152601960248201527f43616e6e6f7420696e766f6b6520746865204368616d6265720000000000000060448201526064016106e3565b6119c583612164565b611a065760405162461bcd60e51b815260206004820152601260248201527115185c99d95d081b9bdd08185b1b1bddd95960721b60448201526064016106e3565b6040516370a0823160e01b81523060048201526000906001600160a01b038816906370a0823190602401602060405180830381865afa158015611a4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a719190613140565b604051636eb1769f60e11b81523060048201526001600160a01b0385811660248301529192506000918b169063dd62ed3e90604401602060405180830381865afa158015611ac3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae79190613140565b905088811015611b1057611b1084611aff838c613076565b6001600160a01b038d169190612518565b611b1a86866125ca565b50604051636eb1769f60e11b81523060048201526001600160a01b0385811660248301528b169063dd62ed3e90604401602060405180830381865afa158015611b67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b8b9190613140565b9050611ba16001600160a01b038b168583612632565b6040516370a0823160e01b81523060048201526000906001600160a01b038a16906370a0823190602401602060405180830381865afa158015611be8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c0c9190613140565b9050611c188382613076565b935087841015611c6a5760405162461bcd60e51b815260206004820152601860248201527f556e646572626f7567687420627579207175616e74697479000000000000000060448201526064016106e3565b50505060018055979650505050505050565b611c8533611239565b611ca15760405162461bcd60e51b81526004016106e390613089565b600154600114611cc35760405162461bcd60e51b81526004016106e39061303c565b6002600190815560115460ff166001811115611ce157611ce16130b3565b14611d275760405162461bcd60e51b8152602060048201526016602482015275139bdb881c99595b9d1c985b98de48185b1b1bddd95960521b60448201526064016106e3565b6011805460ff1916905560005b600954811015611e8a57600060098281548110611d5357611d53613111565b60009182526020822001546040516370a0823160e01b81523060048201526001600160a01b03909116925082906370a0823190602401602060405180830381865afa158015611da6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dca9190613140565b90506000611e086004547f000000000000000000000000000000000000000000000000000000000000000060ff16846127459092919063ffffffff16565b905060008111611e5a5760405162461bcd60e51b815260206004820152601960248201527f5a65726f207175616e74697479206e6f7420616c6c6f7765640000000000000060448201526064016106e3565b6001600160a01b039092166000908152600a60205260409020919091555080611e8281613127565b915050611d34565b50601180546001919060ff1916828061098a565b42841015611eee5760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f4558504952454400000000000000000060448201526064016106e3565b60006001611efa610e8e565b6001600160a01b038a811660008181526007602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015612006573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381161580159061203c5750876001600160a01b0316816001600160a01b0316145b6120795760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b60448201526064016106e3565b6001600160a01b0390811660009081526006602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b6000546001600160a01b0316331461210c5760405162461bcd60e51b81526004016106e3906130eb565b600080546001600160a01b0319166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b60006106b8600d8361242c565b60006106b8600f8361242c565b6000612186836001600160a01b0384166127b0565b9392505050565b6000612186836001600160a01b0384166127ff565b600080612208848054806020026020016040519081016040528092919081815260200182805480156121fd57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116121df575b5050505050846128f2565b91509150806122505760405162461bcd60e51b815260206004820152601460248201527341646472657373206e6f7420696e20617272617960601b60448201526064016106e3565b835460009061226190600190613076565b90508083146122db5784818154811061227c5761227c613111565b9060005260206000200160009054906101000a90046001600160a01b03168584815481106122ac576122ac613111565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b848054806122eb576122eb613159565b600082815260209020810160001990810180546001600160a01b0319169055019055505b50505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6002604051612347919061316f565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b80600460008282546123c1919061320e565b90915550506001600160a01b03821660008181526005602090815260408083208054860190555184815260008051602061336783398151915291015b60405180910390a35050565b6060600061218683612965565b60008061242384846128f2565b95945050505050565b6001600160a01b03811660009081526001830160205260408120541515612186565b6001600160a01b03821660009081526005602052604081208054839290612476908490613076565b90915550506004805482900390556040518181526000906001600160a01b03841690600080516020613367833981519152906020016123fd565b6040516001600160a01b03831660248201526044810182905261251390849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526129c1565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015612569573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061258d9190613140565b612597919061320e565b6040516001600160a01b03851660248201526044810182905290915061230f90859063095ea7b360e01b906064016124dc565b60606125df6001600160a01b03831684612a93565b905060008151116106b85760405162461bcd60e51b815260206004820152601d60248201527f4c6f77206c6576656c2066756e6374696f6e43616c6c206661696c656400000060448201526064016106e3565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301526000919085169063dd62ed3e90604401602060405180830381865afa158015612682573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126a69190613140565b90508181101561270a5760405162461bcd60e51b815260206004820152602960248201527f5361666545524332303a2064656372656173656420616c6c6f77616e63652062604482015268656c6f77207a65726f60b81b60648201526084016106e3565b6040516001600160a01b0384166024820152828203604482018190529061273e90869063095ea7b360e01b906064016124dc565b5050505050565b60008260000361278c5760405162461bcd60e51b8152602060048201526012602482015271043616e6e6f742064697669646520627920360741b60448201526064016106e3565b600061279983600a613305565b9050836127a68287613311565b6124239190613328565b60008181526001830160205260408120546127f7575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106b8565b5060006106b8565b600081815260018301602052604081205480156128e8576000612823600183613076565b855490915060009061283790600190613076565b905081811461289c57600086600001828154811061285757612857613111565b906000526020600020015490508087600001848154811061287a5761287a613111565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806128ad576128ad613159565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106b8565b60009150506106b8565b81516000908190815b8181101561295457846001600160a01b031686828151811061291f5761291f613111565b60200260200101516001600160a01b0316036129425792506001915061295e9050565b8061294c81613127565b9150506128fb565b5060008092509250505b9250929050565b6060816000018054806020026020016040519081016040528092919081815260200182805480156129b557602002820191906000526020600020905b8154815260200190600101908083116129a1575b50505050509050919050565b6000612a16826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612ad79092919063ffffffff16565b8051909150156125135780806020019051810190612a3491906130c9565b6125135760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016106e3565b6060612186838360006040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c65640000815250612aee565b6060612ae68484600085612aee565b949350505050565b606082471015612b4f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016106e3565b600080866001600160a01b03168587604051612b6b919061334a565b60006040518083038185875af1925050503d8060008114612ba8576040519150601f19603f3d011682016040523d82523d6000602084013e612bad565b606091505b5091509150612bbe87838387612bc9565b979650505050505050565b60608315612c38578251600003612c31576001600160a01b0385163b612c315760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016106e3565b5081612ae6565b612ae68383815115612c4d5781518083602001fd5b8060405162461bcd60e51b81526004016106e39190612c8b565b60005b83811015612c82578181015183820152602001612c6a565b50506000910152565b6020815260008251806020840152612caa816040850160208701612c67565b601f01601f19169190910160400192915050565b6001600160a01b0381168114612cd357600080fd5b50565b8035612ce181612cbe565b919050565b60008060408385031215612cf957600080fd5b8235612d0481612cbe565b946020939093013593505050565b600060208284031215612d2457600080fd5b813561218681612cbe565b600080600060608486031215612d4457600080fd5b8335612d4f81612cbe565b92506020840135612d5f81612cbe565b929592945050506040919091013590565b6020808252825182820181905260009190848201906040850190845b81811015612db15783516001600160a01b031683529284019291840191600101612d8c565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612db157835183529284019291840191600101612dd9565b600060208284031215612e0757600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b600080600080600080600060e0888a031215612e3f57600080fd5b8735612e4a81612cbe565b9650602088013595506040880135612e6181612cbe565b945060608801359350608088013567ffffffffffffffff80821115612e8557600080fd5b818a0191508a601f830112612e9957600080fd5b813581811115612eab57612eab612e0e565b604051601f8201601f19908116603f01168101908382118183101715612ed357612ed3612e0e565b816040528281528d6020848701011115612eec57600080fd5b826020860160208301376000602084830101528097505050505050612f1360a08901612cd6565b9150612f2160c08901612cd6565b905092959891949750929550565b600080600080600080600060e0888a031215612f4a57600080fd5b8735612f5581612cbe565b96506020880135612f6581612cbe565b95506040880135945060608801359350608088013560ff81168114612f8957600080fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215612fb957600080fd5b8235612fc481612cbe565b91506020830135612fd481612cbe565b809150509250929050565b600181811c90821680612ff357607f821691505b60208210810361120957634e487b7160e01b600052602260045260246000fd5b6020808252600f908201526e26bab9ba1031329026b0b730b3b2b960891b604082015260600190565b6020808252600a90820152695245454e5452414e435960b01b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b818103818111156106b8576106b8613060565b60208082526010908201526f135d5cdd0818994818481dda5e985c9960821b604082015260600190565b634e487b7160e01b600052602160045260246000fd5b6000602082840312156130db57600080fd5b8151801515811461218657600080fd5b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60006001820161313957613139613060565b5060010190565b60006020828403121561315257600080fd5b5051919050565b634e487b7160e01b600052603160045260246000fd5b600080835481600182811c91508083168061318b57607f831692505b602080841082036131aa57634e487b7160e01b86526022600452602486fd5b8180156131be57600181146131d357613200565b60ff1986168952841515850289019650613200565b60008a81526020902060005b868110156131f85781548b8201529085019083016131df565b505084890196505b509498975050505050505050565b808201808211156106b8576106b8613060565b600181815b8085111561325c57816000190482111561324257613242613060565b8085161561324f57918102915b93841c9390800290613226565b509250929050565b600082613273575060016106b8565b81613280575060006106b8565b816001811461329657600281146132a0576132bc565b60019150506106b8565b60ff8411156132b1576132b1613060565b50506001821b6106b8565b5060208310610133831016604e8410600b84101617156132df575081810a6106b8565b6132e98383613221565b80600019048211156132fd576132fd613060565b029392505050565b60006121868383613264565b80820281158282048414176106b8576106b8613060565b60008261334557634e487b7160e01b600052601260045260246000fd5b500490565b6000825161335c818460208701612c67565b919091019291505056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212200516b1ac2bba32d651fe027f188a4ba5c3618cdf9de7f62151b83649cf5cc92b64736f6c634300081100330000000000000000000000009e9a020a11aea5923500408c14c14a6117d3b32a00000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000001741726368204d6f64657261746520506f7274666f6c696f0000000000000000000000000000000000000000000000000000000000000000000000000000000004414d4f44000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000ab1b1680f6037006e337764547fb82d17606c187000000000000000000000000027af1e12a5869ed329be4c05617ad528e997d5a0000000000000000000000009a41e03fef7f16f552c6fba37ffa7590fb1ec0c4000000000000000000000000bcd2c5c78000504efbc1ce6489dfcac71835406a00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000371211f58d2ca0000000000000000000000000000000000000000000000000005c181da3bbea60000000000000000000000000000000000000000000000000004c4dd227810e5000000000000000000000000000000000000000000000000000d179dde9d041800000000000000000000000000000000000000000000000000000000000000000300000000000000000000000060f56236cd3c1ac146bd94f2006a1335baa4c449000000000000000000000000dd5211d669f5b1f19991819bbd8b220dbbf8062e00000000000000000000000013541ea37cfb0ce3bff8f28d468d93b348bcddea00000000000000000000000000000000000000000000000000000000000000010000000000000000000000009e9a020a11aea5923500408c14c14a6117d3b32a
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102535760003560e01c8063792b1ed911610146578063a9059cbb116100c3578063d36fc0ff11610087578063d36fc0ff14610544578063d505accf1461054c578063dd62ed3e1461055f578063f2fde38b1461058a578063f3ae24151461059d578063f43b8555146105b057600080fd5b8063a9059cbb146104f0578063ac18de4314610503578063b94473ea14610516578063c3b35a7e1461051e578063c8f4feea1461053157600080fd5b806395d89b411161010a57806395d89b41146104a75780639800fc16146104af5780639908c590146104c25780639dc29fac146104d5578063a8d088bb146104e857600080fd5b8063792b1ed9146104215780637df21519146104365780637ecebe00146104615780638da5cb5b1461048157806395ad97fd1461049457600080fd5b8063313ce567116101d45780634199459f116101985780634199459f146103b1578063538741c5146103d1578063585faa2d146103e65780636a76d37b146103ee57806370a082311461040157600080fd5b8063313ce56714610342578063315749fb1461037b5780633644e5151461038357806337c1fe541461038b57806340c10f191461039e57600080fd5b806323b872dd1161021b57806323b872dd146102ee57806324aa15d7146103015780632a286cdf146103095780632c56462f1461031c5780632d06177a1461032f57600080fd5b806306fdde0314610258578063095ea7b314610276578063129928091461029957806312ab980b146102d057806318160ddd146102e5575b600080fd5b6102606105c3565b60405161026d9190612c8b565b60405180910390f35b610289610284366004612ce6565b610651565b604051901515815260200161026d565b6102c26102a7366004612d12565b6001600160a01b03166000908152600a602052604090205490565b60405190815260200161026d565b6102e36102de366004612d12565b6106be565b005b6102c260045481565b6102896102fc366004612d2f565b6107e9565b6102e36108c9565b6102e3610317366004612d12565b610995565b6102e361032a366004612d12565b610a72565b6102e361033d366004612d12565b610c61565b6103697f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff909116815260200161026d565b6102e3610dd7565b6102c2610e8e565b6102e3610399366004612d12565b610ee9565b6102e36103ac366004612ce6565b611007565b6102c26103bf366004612d12565b600a6020526000908152604090205481565b6103d9611065565b60405161026d9190612d70565b6103d9611071565b6102896103fc366004612d12565b6110d3565b6102c261040f366004612d12565b60056020526000908152604090205481565b610429611142565b60405161026d9190612dbd565b610449610444366004612df5565b61120f565b6040516001600160a01b03909116815260200161026d565b6102c261046f366004612d12565b60076020526000908152604090205481565b600054610449906001600160a01b031681565b6102896104a2366004612d12565b611239565b610260611246565b6102e36104bd366004612d12565b611253565b6102e36104d0366004612d12565b611376565b6102e36104e3366004612ce6565b611563565b6103d96115b9565b6102896104fe366004612ce6565b6115c5565b6102e3610511366004612d12565b61162b565b6103d961174b565b6102e361052c366004612d2f565b611757565b6102c261053f366004612e24565b611916565b6102e3611c7c565b6102e361055a366004612f2f565b611e9e565b6102c261056d366004612fa6565b600660209081526000928352604080842090915290825290205481565b6102e3610598366004612d12565b6120e2565b6102896105ab366004612d12565b612157565b6102896105be366004612d12565b612164565b600280546105d090612fdf565b80601f01602080910402602001604051908101604052809291908181526020018280546105fc90612fdf565b80156106495780601f1061061e57610100808354040283529160200191610649565b820191906000526020600020905b81548152906001019060200180831161062c57829003601f168201915b505050505081565b3360008181526006602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106ac9086815260200190565b60405180910390a35060015b92915050565b6106c733612157565b6106ec5760405162461bcd60e51b81526004016106e390613013565b60405180910390fd5b60015460011461070e5760405162461bcd60e51b81526004016106e39061303c565b600260015561071c81611239565b6107605760405162461bcd60e51b81526020600482015260156024820152742bb4bd30b932103737ba1034b71031b430b6b132b960591b60448201526064016106e3565b61076b600b8261218d565b6107ae5760405162461bcd60e51b815260206004820152601460248201527310d85b9b9bdd081c995b5bdd99481dda5e985c9960621b60448201526064016106e3565b6040516001600160a01b038216907f35014a11db7bdb4adb31405c5c7646a3a45bb66c22b5528b37645f2bcb88bea990600090a25060018055565b6001600160a01b03831660009081526006602090815260408083203384529091528120546000198114610845576108208382613076565b6001600160a01b03861660009081526006602090815260408083203384529091529020555b6001600160a01b0385166000908152600560205260408120805485929061086d908490613076565b90915550506001600160a01b0380851660008181526005602052604090819020805487019055519091871690600080516020613367833981519152906108b69087815260200190565b60405180910390a3506001949350505050565b6108d233611239565b6108ee5760405162461bcd60e51b81526004016106e390613089565b6001546001146109105760405162461bcd60e51b81526004016106e39061303c565b6002600155600060115460ff16600181111561092e5761092e6130b3565b1461097b5760405162461bcd60e51b815260206004820152601860248201527f4368616d62657220616c726561647920756e6c6f636b6564000000000000000060448201526064016106e3565b601180546001919060ff191682805b021790555060018055565b61099e33611239565b6109ba5760405162461bcd60e51b81526004016106e390613089565b6001546001146109dc5760405162461bcd60e51b81526004016106e39061303c565b60026001556109ea816110d3565b610a2c5760405162461bcd60e51b8152602060048201526013602482015272135d5cdd0818994818dbdb9cdd1a5d1d595b9d606a1b60448201526064016106e3565b610a376009826121a2565b6040516001600160a01b038216907f7146b276c069596d9ba13f415f0815827f3f72bc58a5e7456f2f375535cd21f390600090a25060018055565b610a7b33612157565b610a975760405162461bcd60e51b81526004016106e390613013565b600154600114610ab95760405162461bcd60e51b81526004016106e39061303c565b600260015560085460405163f43b855560e01b81526001600160a01b0383811660048301529091169063f43b855590602401602060405180830381865afa158015610b08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2c91906130c9565b610b835760405162461bcd60e51b815260206004820152602260248201527f436f6e7472616374206e6f7420616c6c6f77656420696e204368616d626572476044820152611bd960f21b60648201526084016106e3565b610b8c81612164565b15610bd95760405162461bcd60e51b815260206004820152601860248201527f436f6e747261637420616c726561647920616c6c6f776564000000000000000060448201526064016106e3565b610be4600f82612171565b610c265760405162461bcd60e51b815260206004820152601360248201527210d85b9b9bdd081859190818dbdb9d1c9858dd606a1b60448201526064016106e3565b6040516001600160a01b038216907f745213c0a7dcd996a1ded5a6943d545aadcdb27ec72b0ec5636da2a8f59fccdd90600090a25060018055565b6000546001600160a01b03163314610c8b5760405162461bcd60e51b81526004016106e3906130eb565b600154600114610cad5760405162461bcd60e51b81526004016106e39061303c565b6002600155610cbb81612157565b15610cfa5760405162461bcd60e51b815260206004820152600f60248201526e20b63932b0b23c9036b0b730b3b2b960891b60448201526064016106e3565b6001600160a01b038116610d505760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f7420616464206e756c6c206164647265737300000000000000000060448201526064016106e3565b610d5b600d82612171565b610d9c5760405162461bcd60e51b815260206004820152601260248201527121b0b73737ba1030b2321036b0b730b3b2b960711b60448201526064016106e3565b6040516001600160a01b038216907f3b4a40cccf2058c593542587329dd385be4f0b588db5471fbd9598e56dd7093a90600090a25060018055565b610de033611239565b610dfc5760405162461bcd60e51b81526004016106e390613089565b600154600114610e1e5760405162461bcd60e51b81526004016106e39061303c565b6002600190815560115460ff166001811115610e3c57610e3c6130b3565b14610e7a5760405162461bcd60e51b815260206004820152600e60248201526d10da185b58995c881b1bd8dad95960921b60448201526064016106e3565b601180546000919060ff191660018361098a565b60007f00000000000000000000000000000000000000000000000000000000000000894614610ec457610ebf612315565b905090565b507f4629856f490d65acf6eebb73991e76d3c76589b8fceb8e2e3b97b8d6ecc8ea7090565b610ef233611239565b610f0e5760405162461bcd60e51b81526004016106e390613089565b600154600114610f305760405162461bcd60e51b81526004016106e39061303c565b6002600155610f3e816110d3565b15610f8b5760405162461bcd60e51b815260206004820152601760248201527f4d757374206e6f7420626520636f6e7374697475656e7400000000000000000060448201526064016106e3565b6009805460018101825560009182527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0180546001600160a01b0319166001600160a01b03841690811790915560405190917f8f63ff8fbc244d116babb3955e18cd1c02d0e8ab77369224288d679f938f81b791a25060018055565b61101033611239565b61102c5760405162461bcd60e51b81526004016106e390613089565b60015460011461104e5760405162461bcd60e51b81526004016106e39061303c565b600260015561105d82826123af565b505060018055565b6060610ebf600f612409565b606060098054806020026020016040519081016040528092919081815260200182805480156110c957602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116110ab575b5050505050905090565b60006106b882600980548060200260200160405190810160405280929190818152602001828054801561112f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611111575b505050505061241690919063ffffffff16565b60095460609060009067ffffffffffffffff81111561116357611163612e0e565b60405190808252806020026020018201604052801561118c578160200160208202803683370190505b50905060005b60095481101561120957600a6000600983815481106111b3576111b3613111565b60009182526020808320909101546001600160a01b0316835282019290925260400190205482518390839081106111ec576111ec613111565b60209081029190910101528061120181613127565b915050611192565b50919050565b6009818154811061121f57600080fd5b6000918252602090912001546001600160a01b0316905081565b60006106b8600b8361242c565b600380546105d090612fdf565b61125c33612157565b6112785760405162461bcd60e51b81526004016106e390613013565b60015460011461129a5760405162461bcd60e51b81526004016106e39061303c565b60026001556112a881612164565b6112eb5760405162461bcd60e51b815260206004820152601460248201527310dbdb9d1c9858dd081b9bdd08185b1b1bddd95960621b60448201526064016106e3565b6112f6600f8261218d565b61133b5760405162461bcd60e51b815260206004820152601660248201527510d85b9b9bdd081c995b5bdd994818dbdb9d1c9858dd60521b60448201526064016106e3565b6040516001600160a01b038216907fac2e940b68b32bc719742a99f71a86e3854dac1225e4b3de2ec392bb9850f41390600090a25060018055565b61137f33612157565b61139b5760405162461bcd60e51b81526004016106e390613013565b6001546001146113bd5760405162461bcd60e51b81526004016106e39061303c565b60026001556008546040516395ad97fd60e01b81526001600160a01b038381166004830152909116906395ad97fd90602401602060405180830381865afa15801561140c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143091906130c9565b6114875760405162461bcd60e51b815260206004820152602260248201527f57697a617264206e6f742076616c69646174656420696e204368616d626572476044820152611bd960f21b60648201526084016106e3565b61149081611239565b156114dd5760405162461bcd60e51b815260206004820152601960248201527f57697a61726420616c726561647920696e204368616d6265720000000000000060448201526064016106e3565b6114e8600b82612171565b6115285760405162461bcd60e51b815260206004820152601160248201527010d85b9b9bdd08185919081dda5e985c99607a1b60448201526064016106e3565b6040516001600160a01b038216907f18c8a5c5e19d4382b64a94b578eb09f7d1797ee3df236dba16efc12bf853bcb590600090a25060018055565b61156c33611239565b6115885760405162461bcd60e51b81526004016106e390613089565b6001546001146115aa5760405162461bcd60e51b81526004016106e39061303c565b600260015561105d828261244e565b6060610ebf600d612409565b336000908152600560205260408120805483919083906115e6908490613076565b90915550506001600160a01b03831660008181526005602052604090819020805485019055513390600080516020613367833981519152906106ac9086815260200190565b6000546001600160a01b031633146116555760405162461bcd60e51b81526004016106e3906130eb565b6001546001146116775760405162461bcd60e51b81526004016106e39061303c565b600260015561168581612157565b6116c15760405162461bcd60e51b815260206004820152600d60248201526c2737ba10309036b0b730b3b2b960991b60448201526064016106e3565b6116cc600d8261218d565b6117105760405162461bcd60e51b815260206004820152601560248201527421b0b73737ba103932b6b7bb329036b0b730b3b2b960591b60448201526064016106e3565b6040516001600160a01b038216907fef69f7d97228658c92417be1b16b19058315de71fecb435d07b7d23728b6bd3190600090a25060018055565b6060610ebf600b612409565b61176033611239565b61177c5760405162461bcd60e51b81526004016106e390613089565b60015460011461179e5760405162461bcd60e51b81526004016106e39061303c565b6002600155801561190d576040516370a0823160e01b81523060048201526000906001600160a01b038516906370a0823190602401602060405180830381865afa1580156117f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118149190613140565b905061182a6001600160a01b03851684846124b0565b6040516370a0823160e01b81523060048201526000906001600160a01b038616906370a0823190602401602060405180830381865afa158015611871573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118959190613140565b90506118a18383613076565b81101561190a5760405162461bcd60e51b815260206004820152603160248201527f4368616d6265722e7769746864726177546f3a20496e76616c696420706f73746044820152702d77697468647261772062616c616e636560781b60648201526084016106e3565b50505b50506001805550565b600061192133611239565b61193d5760405162461bcd60e51b81526004016106e390613089565b60015460011461195f5760405162461bcd60e51b81526004016106e39061303c565b6002600155306001600160a01b038416036119bc5760405162461bcd60e51b815260206004820152601960248201527f43616e6e6f7420696e766f6b6520746865204368616d6265720000000000000060448201526064016106e3565b6119c583612164565b611a065760405162461bcd60e51b815260206004820152601260248201527115185c99d95d081b9bdd08185b1b1bddd95960721b60448201526064016106e3565b6040516370a0823160e01b81523060048201526000906001600160a01b038816906370a0823190602401602060405180830381865afa158015611a4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a719190613140565b604051636eb1769f60e11b81523060048201526001600160a01b0385811660248301529192506000918b169063dd62ed3e90604401602060405180830381865afa158015611ac3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae79190613140565b905088811015611b1057611b1084611aff838c613076565b6001600160a01b038d169190612518565b611b1a86866125ca565b50604051636eb1769f60e11b81523060048201526001600160a01b0385811660248301528b169063dd62ed3e90604401602060405180830381865afa158015611b67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b8b9190613140565b9050611ba16001600160a01b038b168583612632565b6040516370a0823160e01b81523060048201526000906001600160a01b038a16906370a0823190602401602060405180830381865afa158015611be8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c0c9190613140565b9050611c188382613076565b935087841015611c6a5760405162461bcd60e51b815260206004820152601860248201527f556e646572626f7567687420627579207175616e74697479000000000000000060448201526064016106e3565b50505060018055979650505050505050565b611c8533611239565b611ca15760405162461bcd60e51b81526004016106e390613089565b600154600114611cc35760405162461bcd60e51b81526004016106e39061303c565b6002600190815560115460ff166001811115611ce157611ce16130b3565b14611d275760405162461bcd60e51b8152602060048201526016602482015275139bdb881c99595b9d1c985b98de48185b1b1bddd95960521b60448201526064016106e3565b6011805460ff1916905560005b600954811015611e8a57600060098281548110611d5357611d53613111565b60009182526020822001546040516370a0823160e01b81523060048201526001600160a01b03909116925082906370a0823190602401602060405180830381865afa158015611da6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dca9190613140565b90506000611e086004547f000000000000000000000000000000000000000000000000000000000000001260ff16846127459092919063ffffffff16565b905060008111611e5a5760405162461bcd60e51b815260206004820152601960248201527f5a65726f207175616e74697479206e6f7420616c6c6f7765640000000000000060448201526064016106e3565b6001600160a01b039092166000908152600a60205260409020919091555080611e8281613127565b915050611d34565b50601180546001919060ff1916828061098a565b42841015611eee5760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f4558504952454400000000000000000060448201526064016106e3565b60006001611efa610e8e565b6001600160a01b038a811660008181526007602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015612006573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381161580159061203c5750876001600160a01b0316816001600160a01b0316145b6120795760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b60448201526064016106e3565b6001600160a01b0390811660009081526006602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b6000546001600160a01b0316331461210c5760405162461bcd60e51b81526004016106e3906130eb565b600080546001600160a01b0319166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b60006106b8600d8361242c565b60006106b8600f8361242c565b6000612186836001600160a01b0384166127b0565b9392505050565b6000612186836001600160a01b0384166127ff565b600080612208848054806020026020016040519081016040528092919081815260200182805480156121fd57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116121df575b5050505050846128f2565b91509150806122505760405162461bcd60e51b815260206004820152601460248201527341646472657373206e6f7420696e20617272617960601b60448201526064016106e3565b835460009061226190600190613076565b90508083146122db5784818154811061227c5761227c613111565b9060005260206000200160009054906101000a90046001600160a01b03168584815481106122ac576122ac613111565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b848054806122eb576122eb613159565b600082815260209020810160001990810180546001600160a01b0319169055019055505b50505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6002604051612347919061316f565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b80600460008282546123c1919061320e565b90915550506001600160a01b03821660008181526005602090815260408083208054860190555184815260008051602061336783398151915291015b60405180910390a35050565b6060600061218683612965565b60008061242384846128f2565b95945050505050565b6001600160a01b03811660009081526001830160205260408120541515612186565b6001600160a01b03821660009081526005602052604081208054839290612476908490613076565b90915550506004805482900390556040518181526000906001600160a01b03841690600080516020613367833981519152906020016123fd565b6040516001600160a01b03831660248201526044810182905261251390849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526129c1565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015612569573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061258d9190613140565b612597919061320e565b6040516001600160a01b03851660248201526044810182905290915061230f90859063095ea7b360e01b906064016124dc565b60606125df6001600160a01b03831684612a93565b905060008151116106b85760405162461bcd60e51b815260206004820152601d60248201527f4c6f77206c6576656c2066756e6374696f6e43616c6c206661696c656400000060448201526064016106e3565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301526000919085169063dd62ed3e90604401602060405180830381865afa158015612682573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126a69190613140565b90508181101561270a5760405162461bcd60e51b815260206004820152602960248201527f5361666545524332303a2064656372656173656420616c6c6f77616e63652062604482015268656c6f77207a65726f60b81b60648201526084016106e3565b6040516001600160a01b0384166024820152828203604482018190529061273e90869063095ea7b360e01b906064016124dc565b5050505050565b60008260000361278c5760405162461bcd60e51b8152602060048201526012602482015271043616e6e6f742064697669646520627920360741b60448201526064016106e3565b600061279983600a613305565b9050836127a68287613311565b6124239190613328565b60008181526001830160205260408120546127f7575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106b8565b5060006106b8565b600081815260018301602052604081205480156128e8576000612823600183613076565b855490915060009061283790600190613076565b905081811461289c57600086600001828154811061285757612857613111565b906000526020600020015490508087600001848154811061287a5761287a613111565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806128ad576128ad613159565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106b8565b60009150506106b8565b81516000908190815b8181101561295457846001600160a01b031686828151811061291f5761291f613111565b60200260200101516001600160a01b0316036129425792506001915061295e9050565b8061294c81613127565b9150506128fb565b5060008092509250505b9250929050565b6060816000018054806020026020016040519081016040528092919081815260200182805480156129b557602002820191906000526020600020905b8154815260200190600101908083116129a1575b50505050509050919050565b6000612a16826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612ad79092919063ffffffff16565b8051909150156125135780806020019051810190612a3491906130c9565b6125135760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016106e3565b6060612186838360006040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c65640000815250612aee565b6060612ae68484600085612aee565b949350505050565b606082471015612b4f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016106e3565b600080866001600160a01b03168587604051612b6b919061334a565b60006040518083038185875af1925050503d8060008114612ba8576040519150601f19603f3d011682016040523d82523d6000602084013e612bad565b606091505b5091509150612bbe87838387612bc9565b979650505050505050565b60608315612c38578251600003612c31576001600160a01b0385163b612c315760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016106e3565b5081612ae6565b612ae68383815115612c4d5781518083602001fd5b8060405162461bcd60e51b81526004016106e39190612c8b565b60005b83811015612c82578181015183820152602001612c6a565b50506000910152565b6020815260008251806020840152612caa816040850160208701612c67565b601f01601f19169190910160400192915050565b6001600160a01b0381168114612cd357600080fd5b50565b8035612ce181612cbe565b919050565b60008060408385031215612cf957600080fd5b8235612d0481612cbe565b946020939093013593505050565b600060208284031215612d2457600080fd5b813561218681612cbe565b600080600060608486031215612d4457600080fd5b8335612d4f81612cbe565b92506020840135612d5f81612cbe565b929592945050506040919091013590565b6020808252825182820181905260009190848201906040850190845b81811015612db15783516001600160a01b031683529284019291840191600101612d8c565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612db157835183529284019291840191600101612dd9565b600060208284031215612e0757600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b600080600080600080600060e0888a031215612e3f57600080fd5b8735612e4a81612cbe565b9650602088013595506040880135612e6181612cbe565b945060608801359350608088013567ffffffffffffffff80821115612e8557600080fd5b818a0191508a601f830112612e9957600080fd5b813581811115612eab57612eab612e0e565b604051601f8201601f19908116603f01168101908382118183101715612ed357612ed3612e0e565b816040528281528d6020848701011115612eec57600080fd5b826020860160208301376000602084830101528097505050505050612f1360a08901612cd6565b9150612f2160c08901612cd6565b905092959891949750929550565b600080600080600080600060e0888a031215612f4a57600080fd5b8735612f5581612cbe565b96506020880135612f6581612cbe565b95506040880135945060608801359350608088013560ff81168114612f8957600080fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215612fb957600080fd5b8235612fc481612cbe565b91506020830135612fd481612cbe565b809150509250929050565b600181811c90821680612ff357607f821691505b60208210810361120957634e487b7160e01b600052602260045260246000fd5b6020808252600f908201526e26bab9ba1031329026b0b730b3b2b960891b604082015260600190565b6020808252600a90820152695245454e5452414e435960b01b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b818103818111156106b8576106b8613060565b60208082526010908201526f135d5cdd0818994818481dda5e985c9960821b604082015260600190565b634e487b7160e01b600052602160045260246000fd5b6000602082840312156130db57600080fd5b8151801515811461218657600080fd5b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60006001820161313957613139613060565b5060010190565b60006020828403121561315257600080fd5b5051919050565b634e487b7160e01b600052603160045260246000fd5b600080835481600182811c91508083168061318b57607f831692505b602080841082036131aa57634e487b7160e01b86526022600452602486fd5b8180156131be57600181146131d357613200565b60ff1986168952841515850289019650613200565b60008a81526020902060005b868110156131f85781548b8201529085019083016131df565b505084890196505b509498975050505050505050565b808201808211156106b8576106b8613060565b600181815b8085111561325c57816000190482111561324257613242613060565b8085161561324f57918102915b93841c9390800290613226565b509250929050565b600082613273575060016106b8565b81613280575060006106b8565b816001811461329657600281146132a0576132bc565b60019150506106b8565b60ff8411156132b1576132b1613060565b50506001821b6106b8565b5060208310610133831016604e8410600b84101617156132df575081810a6106b8565b6132e98383613221565b80600019048211156132fd576132fd613060565b029392505050565b60006121868383613264565b80820281158282048414176106b8576106b8613060565b60008261334557634e487b7160e01b600052601260045260246000fd5b500490565b6000825161335c818460208701612c67565b919091019291505056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212200516b1ac2bba32d651fe027f188a4ba5c3618cdf9de7f62151b83649cf5cc92b64736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000009e9a020a11aea5923500408c14c14a6117d3b32a00000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000001741726368204d6f64657261746520506f7274666f6c696f0000000000000000000000000000000000000000000000000000000000000000000000000000000004414d4f44000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000ab1b1680f6037006e337764547fb82d17606c187000000000000000000000000027af1e12a5869ed329be4c05617ad528e997d5a0000000000000000000000009a41e03fef7f16f552c6fba37ffa7590fb1ec0c4000000000000000000000000bcd2c5c78000504efbc1ce6489dfcac71835406a00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000371211f58d2ca0000000000000000000000000000000000000000000000000005c181da3bbea60000000000000000000000000000000000000000000000000004c4dd227810e5000000000000000000000000000000000000000000000000000d179dde9d041800000000000000000000000000000000000000000000000000000000000000000300000000000000000000000060f56236cd3c1ac146bd94f2006a1335baa4c449000000000000000000000000dd5211d669f5b1f19991819bbd8b220dbbf8062e00000000000000000000000013541ea37cfb0ce3bff8f28d468d93b348bcddea00000000000000000000000000000000000000000000000000000000000000010000000000000000000000009e9a020a11aea5923500408c14c14a6117d3b32a
-----Decoded View---------------
Arg [0] : _owner (address): 0x9e9A020A11aEa5923500408c14c14a6117d3B32a
Arg [1] : _name (string): Arch Moderate Portfolio
Arg [2] : _symbol (string): AMOD
Arg [3] : _constituents (address[]): 0xAb1B1680f6037006e337764547fb82d17606c187,0x027aF1E12a5869eD329bE4c05617AD528E997D5A,0x9a41E03fEF7f16f552C6FbA37fFA7590fb1Ec0c4,0xBcD2C5C78000504EFBC1cE6489dfcaC71835406A
Arg [4] : _quantities (uint256[]): 248015873000000000,414755415000000000,343642611700000000,943396226400000000
Arg [5] : _wizards (address[]): 0x60F56236CD3C1Ac146BD94F2006a1335BaA4c449,0xDD5211D669f5B1f19991819Bbd8B220DbBf8062E,0x13541eA37cfB0cE3bfF8f28D468D93b348BcDdea
Arg [6] : _managers (address[]): 0x9e9A020A11aEa5923500408c14c14a6117d3B32a
-----Encoded View---------------
27 Constructor Arguments found :
Arg [0] : 0000000000000000000000009e9a020a11aea5923500408c14c14a6117d3b32a
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000200
Arg [5] : 00000000000000000000000000000000000000000000000000000000000002a0
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000320
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000017
Arg [8] : 41726368204d6f64657261746520506f7274666f6c696f000000000000000000
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [10] : 414d4f4400000000000000000000000000000000000000000000000000000000
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [12] : 000000000000000000000000ab1b1680f6037006e337764547fb82d17606c187
Arg [13] : 000000000000000000000000027af1e12a5869ed329be4c05617ad528e997d5a
Arg [14] : 0000000000000000000000009a41e03fef7f16f552c6fba37ffa7590fb1ec0c4
Arg [15] : 000000000000000000000000bcd2c5c78000504efbc1ce6489dfcac71835406a
Arg [16] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [17] : 0000000000000000000000000000000000000000000000000371211f58d2ca00
Arg [18] : 00000000000000000000000000000000000000000000000005c181da3bbea600
Arg [19] : 00000000000000000000000000000000000000000000000004c4dd227810e500
Arg [20] : 0000000000000000000000000000000000000000000000000d179dde9d041800
Arg [21] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [22] : 00000000000000000000000060f56236cd3c1ac146bd94f2006a1335baa4c449
Arg [23] : 000000000000000000000000dd5211d669f5b1f19991819bbd8b220dbbf8062e
Arg [24] : 00000000000000000000000013541ea37cfb0ce3bff8f28d468d93b348bcddea
Arg [25] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [26] : 0000000000000000000000009e9a020a11aea5923500408c14c14a6117d3b32a
Loading...
Loading
OVERVIEW
Grow a well-diversified crypto portfolio in minutes, professionally built, gaining exposure to the best Web3 assets in a reliable wayLoading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 28.64% | $18.25 | 9,279.4039 | $169,349.12 | |
ETH | 17.79% | $12.41 | 8,476.8221 | $105,197.36 | |
ETH | 9.49% | $261.2 | 214.8986 | $56,131.5 | |
ETH | 6.71% | $6.51 | 6,095.1673 | $39,679.54 | |
ETH | 5.25% | $0.783003 | 39,657.4057 | $31,051.87 | |
ETH | 4.84% | $0.183925 | 155,556.1338 | $28,610.66 | |
ETH | 3.58% | $1.44 | 14,689.3826 | $21,152.71 | |
ETH | 3.49% | $0.523523 | 39,471.6991 | $20,664.34 | |
ETH | 3.38% | $1,315.81 | 15.2075 | $20,010.23 | |
ETH | 3.13% | $1.11 | 16,651.5652 | $18,483.24 | |
ETH | 2.72% | $0.031154 | 516,952.9319 | $16,105.36 | |
ETH | 2.49% | $0.449709 | 32,721.5953 | $14,715.2 | |
ETH | 2.46% | $0.758335 | 19,187.1581 | $14,550.29 | |
ETH | 2.42% | $28.67 | 498.3912 | $14,288.88 | |
ETH | 2.31% | $0.020335 | 670,569.283 | $13,636.09 | |
ETH | 1.30% | $3.46 | 2,227.405 | $7,706.82 | |
BASE | <0.01% | $0.015734 | 320 | $5.03 |
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.