POL Price: $0.417433 (-7.85%)
Gas: 81 GWei
 

Overview

POL Balance

Polygon PoS Chain LogoPolygon PoS Chain LogoPolygon PoS Chain Logo0 POL

POL Value

$0.00

Token Holdings

Multichain Info

Transaction Hash
Method
Block
From
To
Transfer500614202023-11-17 17:14:13422 days ago1700241253IN
Arch: AMOD Token
0 POL0.0019743167.07131627
Approve500608892023-11-17 16:55:19422 days ago1700240119IN
Arch: AMOD Token
0 POL0.0035611676.67162014
Transfer500608442023-11-17 16:53:42422 days ago1700240022IN
Arch: AMOD Token
0 POL0.002327867.99282761
Transfer500599492023-11-17 16:21:25422 days ago1700238085IN
Arch: AMOD Token
0 POL0.00305843103.90103774
Transfer500589112023-11-17 15:44:36422 days ago1700235876IN
Arch: AMOD Token
0 POL0.00713802208.64102258
Approve500583052023-11-17 15:23:10422 days ago1700234590IN
Arch: AMOD Token
0 POL0.00590527127.14016838
Approve500581062023-11-17 15:15:35422 days ago1700234135IN
Arch: AMOD Token
0 POL0.00644111138.67674732
Transfer500287782023-11-16 21:34:35423 days ago1700170475IN
Arch: AMOD Token
0 POL0.065006151,900.09800074
Transfer499410102023-11-14 17:13:07425 days ago1699981987IN
Arch: AMOD Token
0 POL0.0014555149.44660574
Approve498969102023-11-13 14:34:54426 days ago1699886094IN
Arch: AMOD Token
0 POL0.00756962162.97328339
Transfer497808072023-11-10 17:03:16429 days ago1699635796IN
Arch: AMOD Token
0 POL0.01154663248.18666292
Approve467441212023-08-25 17:02:07506 days ago1692982927IN
Arch: AMOD Token
0 POL0.0041729789.84370463
Approve454684352023-07-24 16:28:09538 days ago1690216089IN
Arch: AMOD Token
0 POL0.0042529292.04063801
Approve454673832023-07-24 15:49:47538 days ago1690213787IN
Arch: AMOD Token
0 POL0.0032406270.13279818

Latest 1 internal transaction

Parent Transaction Hash Block From To
420728972023-04-28 21:40:57625 days ago1682718057  Contract Creation0 POL
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Chamber

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 13 : Chamber.sol
/**
 *     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);
    }
}

File 2 of 13 : SafeERC20.sol
// 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");
        }
    }
}

File 3 of 13 : IERC20.sol
// 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);
}

File 4 of 13 : ERC20.sol
// 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);
    }
}

File 5 of 13 : Owned.sol
// 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);
    }
}

File 6 of 13 : ReentrancyGuard.sol
// 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;
    }
}

File 7 of 13 : EnumerableSet.sol
// 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;
    }
}

File 8 of 13 : ArrayUtils.sol
/**
 *     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]);
    }
}

File 9 of 13 : IChamberGod.sol
/**
 *     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);
}

File 10 of 13 : IChamber.sol
/**
 *     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);
}

File 11 of 13 : PreciseUnitMath.sol
/**
 *     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;
    }
}

File 12 of 13 : Address.sol
// 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);
        }
    }
}

File 13 of 13 : IERC20Permit.sol
// 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);
}

Settings
{
  "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

Contract ABI

[{"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"}]

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


Block Transaction Gas Used Reward
view all blocks produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading

OVERVIEW

Grow a well-diversified crypto portfolio in minutes, professionally built, gaining exposure to the best Web3 assets in a reliable way

Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Chain Token Portfolio % Price Amount Value
ETH28.64%$18.259,279.4039$169,349.12
ETH17.79%$12.418,476.8221$105,197.36
ETH9.49%$261.2214.8986$56,131.5
ETH6.71%$6.516,095.1673$39,679.54
ETH5.25%$0.78300339,657.4057$31,051.87
ETH4.84%$0.183925155,556.1338$28,610.66
ETH3.58%$1.4414,689.3826$21,152.71
ETH3.49%$0.52352339,471.6991$20,664.34
ETH3.38%$1,315.8115.2075$20,010.23
ETH3.13%$1.1116,651.5652$18,483.24
ETH2.72%$0.031154516,952.9319$16,105.36
ETH2.49%$0.44970932,721.5953$14,715.2
ETH2.46%$0.75833519,187.1581$14,550.29
ETH2.42%$28.67498.3912$14,288.88
ETH2.31%$0.020335670,569.283$13,636.09
ETH1.30%$3.462,227.405$7,706.82
BASE<0.01%$0.015734320$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.