ETH Price: $3,227.14 (+3.65%)

Contract

0x0000000000aec84F5BFc2af15EAfb943bf4e3522
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Create212625152024-11-25 4:54:4750 days ago1732510487IN
0x00000000...3bf4e3522
0 ETH0.00331767.29736739
Create212349062024-11-21 8:27:2354 days ago1732177643IN
0x00000000...3bf4e3522
0 ETH0.0048367810.12287216
Create211836352024-11-14 4:46:1161 days ago1731559571IN
0x00000000...3bf4e3522
0 ETH0.0156917227.76279896
Create211835932024-11-14 4:37:4761 days ago1731559067IN
0x00000000...3bf4e3522
0 ETH0.016476529.15189135
Create211834882024-11-14 4:16:4761 days ago1731557807IN
0x00000000...3bf4e3522
0 ETH0.0187501333.17885899
Create210179142024-10-22 1:43:4784 days ago1729561427IN
0x00000000...3bf4e3522
0 ETH0.003325935.88558055
Create210123702024-10-21 7:10:3585 days ago1729494635IN
0x00000000...3bf4e3522
0 ETH0.004314289.49166581
Create207094442024-09-09 0:22:59127 days ago1725841379IN
0x00000000...3bf4e3522
0 ETH0.000709421.56029092
Create206406432024-08-30 9:57:47137 days ago1725011867IN
0x00000000...3bf4e3522
0 ETH0.000688381.00714157
Create206273622024-08-28 13:23:23139 days ago1724851403IN
0x00000000...3bf4e3522
0 ETH0.000810771.7834163
Create206226042024-08-27 21:26:47140 days ago1724794007IN
0x00000000...3bf4e3522
0 ETH0.001083012.3819475
Create206198832024-08-27 12:20:35140 days ago1724761235IN
0x00000000...3bf4e3522
0 ETH0.000846851.86249768
Create206198292024-08-27 12:09:35140 days ago1724760575IN
0x00000000...3bf4e3522
0 ETH0.00090841.99821484
Create206197552024-08-27 11:54:47140 days ago1724759687IN
0x00000000...3bf4e3522
0 ETH0.000721831.58794506
Create206197022024-08-27 11:44:11140 days ago1724759051IN
0x00000000...3bf4e3522
0 ETH0.000688551.51405641
Create206196012024-08-27 11:23:59140 days ago1724757839IN
0x00000000...3bf4e3522
0 ETH0.001023341.81052781
Create206194432024-08-27 10:52:23140 days ago1724755943IN
0x00000000...3bf4e3522
0 ETH0.00071691.57705335
Create205849742024-08-22 15:14:59145 days ago1724339699IN
0x00000000...3bf4e3522
0 ETH0.001334552.93547579
Create205421672024-08-16 15:43:59151 days ago1723823039IN
0x00000000...3bf4e3522
0 ETH0.002957095.15957622
Create204533292024-08-04 6:14:59163 days ago1722752099IN
0x00000000...3bf4e3522
0 ETH0.000632351.11856604
Create204523772024-08-04 3:04:23163 days ago1722740663IN
0x00000000...3bf4e3522
0 ETH0.000805441.36881626
Create204147292024-07-29 20:51:35169 days ago1722286295IN
0x00000000...3bf4e3522
0 ETH0.001471332.60313217
Create203712142024-07-23 19:06:23175 days ago1721761583IN
0x00000000...3bf4e3522
0 ETH0.003758975.46884547
Create203289642024-07-17 21:33:59180 days ago1721252039IN
0x00000000...3bf4e3522
0 ETH0.002600685.72073774
Create202814252024-07-11 6:19:23187 days ago1720678763IN
0x00000000...3bf4e3522
0 ETH0.001077242.36862151
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block
From
To
212625152024-11-25 4:54:4750 days ago1732510487
0x00000000...3bf4e3522
 Contract Creation0 ETH
212349062024-11-21 8:27:2354 days ago1732177643
0x00000000...3bf4e3522
 Contract Creation0 ETH
211836352024-11-14 4:46:1161 days ago1731559571
0x00000000...3bf4e3522
 Contract Creation0 ETH
211835932024-11-14 4:37:4761 days ago1731559067
0x00000000...3bf4e3522
 Contract Creation0 ETH
211834882024-11-14 4:16:4761 days ago1731557807
0x00000000...3bf4e3522
 Contract Creation0 ETH
210179142024-10-22 1:43:4784 days ago1729561427
0x00000000...3bf4e3522
 Contract Creation0 ETH
210123702024-10-21 7:10:3585 days ago1729494635
0x00000000...3bf4e3522
 Contract Creation0 ETH
207094442024-09-09 0:22:59127 days ago1725841379
0x00000000...3bf4e3522
 Contract Creation0 ETH
206406432024-08-30 9:57:47137 days ago1725011867
0x00000000...3bf4e3522
 Contract Creation0 ETH
206273622024-08-28 13:23:23139 days ago1724851403
0x00000000...3bf4e3522
 Contract Creation0 ETH
206226042024-08-27 21:26:47140 days ago1724794007
0x00000000...3bf4e3522
 Contract Creation0 ETH
206198832024-08-27 12:20:35140 days ago1724761235
0x00000000...3bf4e3522
 Contract Creation0 ETH
206198292024-08-27 12:09:35140 days ago1724760575
0x00000000...3bf4e3522
 Contract Creation0 ETH
206197552024-08-27 11:54:47140 days ago1724759687
0x00000000...3bf4e3522
 Contract Creation0 ETH
206197022024-08-27 11:44:11140 days ago1724759051
0x00000000...3bf4e3522
 Contract Creation0 ETH
206196012024-08-27 11:23:59140 days ago1724757839
0x00000000...3bf4e3522
 Contract Creation0 ETH
206194432024-08-27 10:52:23140 days ago1724755943
0x00000000...3bf4e3522
 Contract Creation0 ETH
205849742024-08-22 15:14:59145 days ago1724339699
0x00000000...3bf4e3522
 Contract Creation0 ETH
205421672024-08-16 15:43:59151 days ago1723823039
0x00000000...3bf4e3522
 Contract Creation0 ETH
204533292024-08-04 6:14:59163 days ago1722752099
0x00000000...3bf4e3522
 Contract Creation0 ETH
204523772024-08-04 3:04:23163 days ago1722740663
0x00000000...3bf4e3522
 Contract Creation0 ETH
204147292024-07-29 20:51:35169 days ago1722286295
0x00000000...3bf4e3522
 Contract Creation0 ETH
203712142024-07-23 19:06:23175 days ago1721761583
0x00000000...3bf4e3522
 Contract Creation0 ETH
203289642024-07-17 21:33:59180 days ago1721252039
0x00000000...3bf4e3522
 Contract Creation0 ETH
202814252024-07-11 6:19:23187 days ago1720678763
0x00000000...3bf4e3522
 Contract Creation0 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SoundCreatorV2

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion, MIT license
File 1 of 12 : SoundCreatorV2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;

import { Clones } from "openzeppelin/proxy/Clones.sol";
import { ReentrancyGuard } from "openzeppelin/security/ReentrancyGuard.sol";
import { ISoundCreatorV2 } from "./interfaces/ISoundCreatorV2.sol";
import { LibMulticaller } from "multicaller/LibMulticaller.sol";
import { Ownable } from "solady/auth/Ownable.sol";
import { EIP712 } from "solady/utils/EIP712.sol";
import { LibZip } from "solady/utils/LibZip.sol";
import { LibBitmap } from "solady/utils/LibBitmap.sol";
import { SafeTransferLib } from "solady/utils/SafeTransferLib.sol";
import { SignatureCheckerLib } from "solady/utils/SignatureCheckerLib.sol";

/**
 * @title SoundCreatorV1
 * @notice A factory that deploys minimal proxies of SoundEditions.
 * @dev The proxies are OpenZeppelin's Clones implementation of https://eips.ethereum.org/EIPS/eip-1167
 */
contract SoundCreatorV2 is ISoundCreatorV2, EIP712, ReentrancyGuard {
    using LibBitmap for LibBitmap.Bitmap;

    // =============================================================
    //                           CONSTANTS
    // =============================================================

    /**
     * @dev For EIP-712 signature digest calculation.
     */
    bytes32 public constant SOUND_CREATION_TYPEHASH =
        // prettier-ignore
        keccak256(
            "SoundCreation("
                "address implementation,"
                "address owner,"
                "bytes32 salt,"
                "bytes initData,"
                "address[] contracts,"
                "bytes[] data,"
                "uint256 nonce"
            ")"
        );

    /**
     * @dev For EIP-712 signature digest calculation.
     */
    bytes32 public constant DOMAIN_TYPEHASH = _DOMAIN_TYPEHASH;

    // =============================================================
    //                            STORAGE
    // =============================================================

    /**
     * @dev For storing the invalidated nonces.
     */
    mapping(address => LibBitmap.Bitmap) internal _invalidatedNonces;

    // =============================================================
    //               PUBLIC / EXTERNAL WRITE FUNCTIONS
    // =============================================================

    /**
     * @inheritdoc ISoundCreatorV2
     */
    function create(SoundCreation calldata c) external nonReentrant returns (address edition, bytes[] memory results) {
        if (c.owner != LibMulticaller.sender()) revert Unauthorized();
        (edition, results) = _create(c);
    }

    /**
     * @inheritdoc ISoundCreatorV2
     */
    function createWithSignature(SoundCreation calldata creation, bytes calldata signature)
        external
        nonReentrant
        returns (address soundEdition, bytes[] memory results)
    {
        (soundEdition, results) = _createWithSignature(creation, signature);
    }

    /**
     * @inheritdoc ISoundCreatorV2
     */
    function mint(
        address minter,
        bytes calldata mintData,
        address refundTo
    ) external payable nonReentrant {
        _mint(minter, mintData, refundTo);
    }

    /**
     * @inheritdoc ISoundCreatorV2
     */
    function createWithSignatureAndMint(
        SoundCreation calldata c,
        bytes calldata signature,
        address minter,
        bytes calldata mintData,
        address refundTo
    ) external payable nonReentrant returns (address edition, bytes[] memory results) {
        // We will skip the `createWithSignature` if the SoundEdtion already exists.
        (, bool exists) = soundEditionAddress(c.implementation, c.owner, c.salt);
        if (!exists) (edition, results) = _createWithSignature(c, signature);
        _mint(minter, mintData, refundTo);
    }

    /**
     * @inheritdoc ISoundCreatorV2
     */
    function invalidateNonces(uint256[] calldata nonces) external {
        unchecked {
            address sender = LibMulticaller.sender();
            LibBitmap.Bitmap storage s = _invalidatedNonces[sender];
            for (uint256 i; i != nonces.length; ++i) {
                s.set(nonces[i]);
            }
            emit NoncesInvalidated(sender, nonces);
        }
    }

    /**
     * @dev For compressed calldata calling.
     */
    fallback() external payable {
        LibZip.cdFallback();
    }

    /**
     * @dev For compressed calldata calling.
     */
    receive() external payable {
        LibZip.cdFallback();
    }

    // =============================================================
    //               PUBLIC / EXTERNAL VIEW FUNCTIONS
    // =============================================================

    /**
     * @inheritdoc ISoundCreatorV2
     */
    function soundEditionAddress(
        address implementation,
        address owner,
        bytes32 salt
    ) public view returns (address addr, bool exists) {
        addr = Clones.predictDeterministicAddress(implementation, _saltedSalt(owner, salt), address(this));
        exists = addr.code.length != 0;
    }

    /**
     * @inheritdoc ISoundCreatorV2
     */
    function isValidSignature(SoundCreation calldata c, bytes calldata signature) public view returns (bool) {
        return
            // Whether the signature is correctly signed. Will revert if recovery fails.
            SignatureCheckerLib.isValidSignatureNowCalldata(c.owner, computeDigest(c), signature) &&
            // And whether the creation's nonce is not invalidated.
            !_invalidatedNonces[c.owner].get(c.nonce);
    }

    /**
     * @inheritdoc ISoundCreatorV2
     */
    function computeDigest(SoundCreation calldata c) public view returns (bytes32) {
        bytes32 encodedDataHash;
        unchecked {
            bytes[] calldata cData = c.data;
            uint256 n = cData.length;
            bytes32[] memory encodedData = new bytes32[](n);
            for (uint256 i = 0; i != n; ++i) {
                encodedData[i] = keccak256(cData[i]);
            }
            encodedDataHash = keccak256(abi.encodePacked(encodedData));
        }
        return
            _hashTypedData(
                keccak256(
                    abi.encode(
                        SOUND_CREATION_TYPEHASH,
                        c.implementation, // address
                        c.owner, // address
                        c.salt, // bytes32
                        keccak256(c.initData), // bytes
                        keccak256(abi.encodePacked(c.contracts)), // address[]
                        encodedDataHash, // bytes[]
                        c.nonce // uint256
                    )
                )
            );
    }

    /**
     * @inheritdoc ISoundCreatorV2
     */
    function noncesInvalidated(address signer, uint256[] calldata nonces) external view returns (bool[] memory result) {
        unchecked {
            result = new bool[](nonces.length);
            LibBitmap.Bitmap storage s = _invalidatedNonces[signer];
            for (uint256 i; i != nonces.length; ++i) {
                result[i] = s.get(nonces[i]);
            }
        }
    }

    // EIP712 parameters.

    /**
     * @inheritdoc ISoundCreatorV2
     */
    function name() external pure returns (string memory name_) {
        (name_, ) = _domainNameAndVersion();
    }

    /**
     * @inheritdoc ISoundCreatorV2
     */
    function version() external pure returns (string memory version_) {
        (, version_) = _domainNameAndVersion();
    }

    /**
     * @inheritdoc ISoundCreatorV2
     */
    function domainSeparator() external view returns (bytes32 separator) {
        separator = _domainSeparator();
    }

    // =============================================================
    //                  INTERNAL / PRIVATE HELPERS
    // =============================================================

    /**
     * @dev Override for EIP-712.
     * @return name_    The EIP-712 name.
     * @return version_ The EIP-712 version.
     */
    function _domainNameAndVersion()
        internal
        pure
        virtual
        override
        returns (string memory name_, string memory version_)
    {
        name_ = "SoundCreator";
        version_ = "2";
    }

    /**
     * @dev Call the `contracts` in order with `data`.
     * @param contracts The addresses of the contracts.
     * @param data      The `abi.encodeWithSelector` calldata for each of the contracts.
     * @return results The results of calling the contracts.
     */
    function _callContracts(address[] calldata contracts, bytes[] calldata data)
        internal
        returns (bytes[] memory results)
    {
        if (contracts.length != data.length) revert ArrayLengthsMismatch();

        assembly {
            // Grab the free memory pointer.
            // We will use the free memory to construct the `results` array,
            // and also as a temporary space for the calldata.
            results := mload(0x40)
            // Set `results.length` to be equal to `data.length`.
            mstore(results, data.length)
            // Skip the first word, which is used to store the length
            let resultsOffsets := add(results, 0x20)
            // Compute the location of the last calldata offset in `data`.
            // `shl(5, n)` is a gas-saving shorthand for `mul(0x20, n)`.
            let dataOffsetsEnd := add(data.offset, shl(5, data.length))
            // This is the start of the unused free memory.
            // We use it to temporarily store the calldata to call the contracts.
            let m := add(resultsOffsets, shl(5, data.length))

            // Loop through `contacts` and `data` together.
            // prettier-ignore
            for { let i := data.offset } iszero(eq(i, dataOffsetsEnd)) { i := add(i, 0x20) } {
                // Location of `bytes[i]` in calldata.
                let o := add(data.offset, calldataload(i))
                // Copy `bytes[i]` from calldata to the free memory.
                calldatacopy(
                    m, // Start of the unused free memory.
                    add(o, 0x20), // Location of starting byte of `data[i]` in calldata.
                    calldataload(o) // The length of the `bytes[i]`.
                )
                // Grab `contracts[i]` from the calldata.
                // As `contracts` is the same length as `data`,
                // `sub(i, data.offset)` gives the relative offset to apply to
                // `contracts.offset` for `contracts[i]` to match `data[i]`.
                let c := calldataload(add(contracts.offset, sub(i, data.offset)))
                // Call the contract, and revert if the call fails.
                if iszero(
                    call(
                        gas(), // Gas remaining.
                        c, // `contracts[i]`.
                        0, // `msg.value` of the call: 0 ETH.
                        m, // Start of the copy of `bytes[i]` in memory.
                        calldataload(o), // The length of the `bytes[i]`.
                        0x00, // Start of output. Not used.
                        0x00 // Size of output. Not used.
                    )
                ) {
                    // Bubble up the revert if the call reverts.
                    returndatacopy(0x00, 0x00, returndatasize())
                    revert(0x00, returndatasize())
                }
                // Append the current `m` into `resultsOffsets`.
                mstore(resultsOffsets, m)
                resultsOffsets := add(resultsOffsets, 0x20)

                // Append the `returndatasize()` to `results`.
                mstore(m, returndatasize())
                // Append the return data to `results`.
                returndatacopy(add(m, 0x20), 0x00, returndatasize())
                // Advance `m` by `returndatasize() + 0x20`,
                // rounded up to the next multiple of 32.
                // `0x3f = 32 + 31`. The mask is `type(uint64).max & ~31`,
                // which is big enough for all purposes (see memory expansion costs).
                m := and(add(add(m, returndatasize()), 0x3f), 0xffffffffffffffe0)
            }
            // Allocate the memory for `results` by updating the free memory pointer.
            mstore(0x40, m)
        }
    }

    /**
     * @dev Returns the salted salt.
     *      To prevent griefing and accidental collisions from clients that don't
     *      generate their salt properly.
     * @param owner The initial owner of the SoundEdition.
     * @param salt  The salt, generated on the client side.
     * @return result The computed value.
     */
    function _saltedSalt(address owner, bytes32 salt) internal view returns (bytes32 result) {
        assembly {
            mstore(0x20, owner)
            mstore(0x0c, chainid())
            mstore(0x00, salt)
            result := keccak256(0x00, 0x40)
        }
    }

    /**
     * @dev Creates a new SoundEdtion via `c.soundCreator`, and a new split contract if needed.
     * @param c The SoundCreation struct.
     * @return edition The address of the created SoundEdition contract.
     * @return results      The results of calling the contracts.
     *                      Use `abi.decode` to decode them.
     */
    function _create(SoundCreation calldata c) internal returns (address edition, bytes[] memory results) {
        if (c.implementation == address(0)) revert ImplementationAddressCantBeZero();

        // Create Sound Edition proxy.
        edition = payable(Clones.cloneDeterministic(c.implementation, _saltedSalt(c.owner, c.salt)));

        bytes calldata initData = c.initData;
        // Initialize proxy.
        assembly {
            // Grab the free memory pointer.
            let m := mload(0x40)
            // Copy the `initData` to the free memory.
            calldatacopy(m, initData.offset, initData.length)
            // Call the initializer, and revert if the call fails.
            if iszero(
                call(
                    gas(), // Gas remaining.
                    edition, // Address of the edition.
                    0, // `msg.value` of the call: 0 ETH.
                    m, // Start of input.
                    initData.length, // Length of input.
                    0x00, // Start of output. Not used.
                    0x00 // Size of output. Not used.
                )
            ) {
                // Bubble up the revert if the call reverts.
                returndatacopy(0x00, 0x00, returndatasize())
                revert(0x00, returndatasize())
            }
        }

        results = _callContracts(c.contracts, c.data);

        Ownable(edition).transferOwnership(c.owner);

        emit Created(c.implementation, edition, c.owner, c.initData, c.contracts, c.data, results);
    }

    /**
     * @dev Creates a SoundEdition on behalf of `c.owner`.
     * @param c  The SoundCreation struct.
     * @param signature The signature for the SoundCreation struct, by `c.owner`.
     * @return edition The address of the created SoundEdition contract.
     * @return results      The results of calling the contracts.
     *                      Use `abi.decode` to decode them.
     */
    function _createWithSignature(SoundCreation calldata c, bytes calldata signature)
        internal
        returns (address edition, bytes[] memory results)
    {
        if (!isValidSignature(c, signature)) revert InvalidSignature();
        (edition, results) = _create(c);

        // Invalidate the nonce and emit the event.
        _invalidatedNonces[c.owner].set(c.nonce);
        uint256[] memory nonces = new uint256[](1);
        nonces[0] = c.nonce;
        emit NoncesInvalidated(c.owner, nonces);
    }

    /**
     * @dev Calls `minter` with `mintData`.
     *      After which, refunds any remaining ETH balance in the adapter contract.
     *      If `minter` is the zero address, the function is a no-op.
     * @param minter   The minter contract to call, SAM included.
     * @param mintData The abi encoded calldata to the minter contract.
     * @param refundTo The address to transfer any remaining ETH in the contract after the calls.
     *                 If `address(0)`, remaining ETH will NOT be refunded.
     *                 If `address(1)`, remaining ETH will be refunded to `msg.sender`.
     *                 If anything else, remaining ETH will be refunded to `refundTo`.
     */
    function _mint(
        address minter,
        bytes calldata mintData,
        address refundTo
    ) internal {
        if (minter == address(0)) return;
        assembly {
            // Grab the free memory pointer.
            let m := mload(0x40)
            // Copy the `mintData` into the free memory.
            calldatacopy(m, mintData.offset, mintData.length)
            // Make a call to `minter` with `mintData`, reverting if the call fails.
            if iszero(
                call(
                    gas(), // Gas remaining.
                    minter, // Address of the minter.
                    callvalue(), // All the ETH sent to this function.
                    m, // Start of the `mintData` in memory.
                    mintData.length, // Length of `mintData`.
                    0x00, // We'll use returndatasize instead.
                    0x00 // We'll use returndatasize instead.
                )
            ) {
                // If the call fails, bubble up the revert.
                returndatacopy(0x00, 0x00, returndatasize())
                revert(0x00, returndatasize())
            }
        }
        if (refundTo != address(0)) {
            // Refund any ETH in this contract. In the unlikely case where ETH is
            // mistakenly sent to this contract, it will be combined into the refund.
            if (address(this).balance != 0) {
                if (refundTo == address(1)) refundTo = msg.sender;
                SafeTransferLib.forceSafeTransferAllETH(refundTo);
            }
        }
    }
}

File 2 of 12 : Clones.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (proxy/Clones.sol)

pragma solidity ^0.8.0;

/**
 * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for
 * deploying minimal proxy contracts, also known as "clones".
 *
 * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
 * > a minimal bytecode implementation that delegates all calls to a known, fixed address.
 *
 * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
 * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
 * deterministic method.
 *
 * _Available since v3.4._
 */
library Clones {
    /**
     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
     *
     * This function uses the create opcode, which should never revert.
     */
    function clone(address implementation) internal returns (address instance) {
        /// @solidity memory-safe-assembly
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
            mstore(add(ptr, 0x14), shl(0x60, implementation))
            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
            instance := create(0, ptr, 0x37)
        }
        require(instance != address(0), "ERC1167: create failed");
    }

    /**
     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
     *
     * This function uses the create2 opcode and a `salt` to deterministically deploy
     * the clone. Using the same `implementation` and `salt` multiple time will revert, since
     * the clones cannot be deployed twice at the same address.
     */
    function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
        /// @solidity memory-safe-assembly
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
            mstore(add(ptr, 0x14), shl(0x60, implementation))
            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
            instance := create2(0, ptr, 0x37, salt)
        }
        require(instance != address(0), "ERC1167: create2 failed");
    }

    /**
     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
     */
    function predictDeterministicAddress(
        address implementation,
        bytes32 salt,
        address deployer
    ) internal pure returns (address predicted) {
        /// @solidity memory-safe-assembly
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
            mstore(add(ptr, 0x14), shl(0x60, implementation))
            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000)
            mstore(add(ptr, 0x38), shl(0x60, deployer))
            mstore(add(ptr, 0x4c), salt)
            mstore(add(ptr, 0x6c), keccak256(ptr, 0x37))
            predicted := keccak256(add(ptr, 0x37), 0x55)
        }
    }

    /**
     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
     */
    function predictDeterministicAddress(address implementation, bytes32 salt)
        internal
        view
        returns (address predicted)
    {
        return predictDeterministicAddress(implementation, salt, address(this));
    }
}

File 3 of 12 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

File 4 of 12 : ISoundCreatorV2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;

/**
 * @title ISoundCreatorV2
 * @notice The interface for the Sound edition factory.
 */
interface ISoundCreatorV2 {
    // =============================================================
    //                            STRUCTS
    // =============================================================

    /**
     * @dev A struct containing all the data required for creating a SoundEdition
     *      and setting up all other relevant contracts.
     */
    struct SoundCreation {
        // The address of the SoundEdition implementation.
        address implementation;
        // The initial owner of the deployed SoundEdition.
        address owner;
        // The salt used for deploying the SoundEdition via the SoundCreator factory.
        bytes32 salt;
        // The calldata passed to the SoundEdition to initialize it.
        bytes initData;
        // Array of contracts to call after initializing the SoundEdition.
        address[] contracts;
        // Array of abi encoded calldata to pass to each entry in `contracts`.
        bytes[] data;
        // The current nonce used to sign the SoundCreation struct, if required.
        // Just generate some really random number on the client side for this.
        uint256 nonce;
    }

    // =============================================================
    //                            EVENTS
    // =============================================================

    /**
     * @dev Emitted when an edition is created.
     * @param implementation The address of the SoundEdition implementation.
     * @param edition        The address of the deployed SoundEdition.
     * @param owner          The address of the owner.
     * @param initData       The calldata to initialize SoundEdition via `abi.encodeWithSelector`.
     * @param contracts      The list of contracts called.
     * @param data           The list of calldata created via `abi.encodeWithSelector`
     * @param results        The results of calling the contracts. Use `abi.decode` to decode them.
     */
    event Created(
        address indexed implementation,
        address indexed edition,
        address indexed owner,
        bytes initData,
        address[] contracts,
        bytes[] data,
        bytes[] results
    );

    /**
     * @dev Emitted when the `nonces` of `signer` are invalidated.
     * @param signer  The signer of the nonces.
     * @param nonces The nonces.
     */
    event NoncesInvalidated(address indexed signer, uint256[] nonces);

    // =============================================================
    //                            ERRORS
    // =============================================================

    /**
     * @dev Thrown if the implementation address is zero.
     */
    error ImplementationAddressCantBeZero();

    /**
     * @dev Thrown if the lengths of the input arrays are not equal.
     */
    error ArrayLengthsMismatch();

    /**
     * @dev Not authorized to perfrom the action.
     */
    error Unauthorized();

    /**
     * @dev The signature for the SoundCreation struct is invalid.
     *      This could be caused be an invalid parameter, signer, or invalidated nonce.
     */
    error InvalidSignature();

    // =============================================================
    //               PUBLIC / EXTERNAL WRITE FUNCTIONS
    // =============================================================

    /**
     * @dev Creates a SoundEdition and sets up all other relevant contracts.
     * @param creation The SoundCreation struct.
     * @return soundEdition The address of the created SoundEdition contract.
     * @return results      The results of calling the contracts.
     *                      Use `abi.decode` to decode them.
     */
    function create(SoundCreation calldata creation) external returns (address soundEdition, bytes[] memory results);

    /**
     * @dev Creates a SoundEdition on behalf of `creation.owner`.
     * @param creation  The SoundCreation struct.
     * @param signature The signature for the SoundCreation struct, by `creation.owner`.
     * @return soundEdition The address of the created SoundEdition contract.
     * @return results      The results of calling the contracts.
     *                      Use `abi.decode` to decode them.
     */
    function createWithSignature(SoundCreation calldata creation, bytes calldata signature)
        external
        returns (address soundEdition, bytes[] memory results);

    /**
     * @dev Calls `minter` with `mintData`.
     *      After which, refunds any remaining ETH balance in the adapter contract.
     *      If `minter` is the zero address, the function is a no-op.
     * @param minter   The minter contract to call, SAM included.
     * @param mintData The abi encoded calldata to the minter contract.
     * @param refundTo The address to transfer any remaining ETH in the contract after the calls.
     *                 If `address(0)`, remaining ETH will NOT be refunded.
     *                 If `address(1)`, remaining ETH will be refunded to `msg.sender`.
     *                 If anything else, remaining ETH will be refunded to `refundTo`.
     */
    function mint(
        address minter,
        bytes calldata mintData,
        address refundTo
    ) external payable;

    /**
     * @dev Equivalent to calling {createWithSignature}, followed by {mint}.
     * @param creation  The SoundCreation struct.
     * @param signature The signature for the SoundCreation struct, by `creation.owner`.
     * @param minter    The minter contract to call, SAM included.
     * @param mintData  The calldata to the minter contract.
     * @param refundTo  The address to transfer any remaining ETH in the contract after the calls.
     *                  If `address(0)`, remaining ETH will NOT be refunded.
     *                  If `address(1)`, remaining ETH will be refunded to `msg.sender`.
     *                  If anything else, remaining ETH will be refunded to `refundTo`.
     * @return soundEdition The address of the created SoundEdition contract.
     * @return results      The results of calling the contracts.
     *                      Use `abi.decode` to decode them.
     */
    function createWithSignatureAndMint(
        SoundCreation calldata creation,
        bytes calldata signature,
        address minter,
        bytes calldata mintData,
        address refundTo
    ) external payable returns (address soundEdition, bytes[] memory results);

    /**
     * @dev Invalidates the nonces for the `msg.sender`.
     * @param nonces The nonces.
     */
    function invalidateNonces(uint256[] calldata nonces) external;

    // =============================================================
    //               PUBLIC / EXTERNAL VIEW FUNCTIONS
    // =============================================================

    /**
     * @dev Returns whether each of the `nonces` of `signer` has been invalidated.
     * @param signer The signer of the signature.
     * @param nonces An array of nonces.
     * @return A bool array representing whether each nonce has been invalidated.
     */
    function noncesInvalidated(address signer, uint256[] calldata nonces) external view returns (bool[] memory);

    /**
     * @dev Returns the deterministic address for the SoundEdition clone.
     * @param implementation The implementation of the SoundEdition.
     * @param owner          The initial owner of the SoundEdition.
     * @param salt           The salt, generated on the client side.
     * @return addr The computed address.
     * @return exists Whether the contract exists.
     */
    function soundEditionAddress(
        address implementation,
        address owner,
        bytes32 salt
    ) external view returns (address addr, bool exists);

    /**
     * @dev Returns if the signature for the creation struct is correctly signed,
     *      as well as the creation's nonce is still valid.
     * @param creation  The SoundCreation struct.
     * @param signature The signature for the SoundCreation struct.
     * @return isValid The computed result.
     */
    function isValidSignature(SoundCreation calldata creation, bytes calldata signature) external view returns (bool);

    /**
     * @dev Computes the EIP-712 hash of the SoundCreation struct.
     * @param creation The SoundCreation struct.
     * @return digest The computed result.
     */
    function computeDigest(SoundCreation calldata creation) external view returns (bytes32 digest);

    /**
     * @dev Returns the SoundCreation struct's EIP-712 typehash.
     * @return The constant value.
     */
    function SOUND_CREATION_TYPEHASH() external view returns (bytes32);

    /**
     * @dev Returns the EIP-712 domain typehash.
     * @return The constant value.
     */
    function DOMAIN_TYPEHASH() external view returns (bytes32);

    /**
     * @dev Returns the EIP-712 domain name.
     * @return name_ The constant value.
     */
    function name() external pure returns (string memory name_);

    /**
     * @dev Returns the EIP-712 domain version.
     * @return version_ The constant value.
     */
    function version() external pure returns (string memory version_);

    /**
     * @dev Returns the EIP-712 domain separator.
     * @return The current value.
     */
    function domainSeparator() external view returns (bytes32);
}

File 5 of 12 : LibMulticaller.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/**
 * @title LibMulticaller
 * @author vectorized.eth
 * @notice Library to read the `msg.sender` of the multicaller with sender contract.
 */
library LibMulticaller {
    /**
     * @dev The address of the multicaller contract.
     */
    address internal constant MULTICALLER = 0x0000000000009448722dAF1A55EF6D1E71FB162d;

    /**
     * @dev The address of the multicaller with sender contract.
     */
    address internal constant MULTICALLER_WITH_SENDER = 0x00000000002Fd5Aeb385D324B580FCa7c83823A0;

    /**
     * @dev The address of the multicaller with signer contract.
     */
    address internal constant MULTICALLER_WITH_SIGNER = 0x000000000000a89360A6a4786b9B33266F208AF4;

    /**
     * @dev Returns the caller of `aggregateWithSender` on `MULTICALLER_WITH_SENDER`.
     */
    function multicallerSender() internal view returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, 0x00)
            if iszero(staticcall(gas(), MULTICALLER_WITH_SENDER, 0x00, 0x00, 0x00, 0x20)) {
                revert(0x00, 0x00) // For better gas estimation.
            }
            result := mload(0x00)
        }
    }

    /**
     * @dev Returns the signer of `aggregateWithSigner` on `MULTICALLER_WITH_SIGNER`.
     */
    function multicallerSigner() internal view returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, 0x00)
            if iszero(staticcall(gas(), MULTICALLER_WITH_SIGNER, 0x00, 0x00, 0x00, 0x20)) {
                revert(0x00, 0x00) // For better gas estimation.
            }
            result := mload(0x00)
        }
    }

    /**
     * @dev Returns the caller of `aggregateWithSender` on `MULTICALLER_WITH_SENDER`,
     *      if the current context's `msg.sender` is `MULTICALLER_WITH_SENDER`.
     *      Otherwise, returns `msg.sender`.
     */
    function sender() internal view returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, caller())
            let withSender := MULTICALLER_WITH_SENDER
            if eq(caller(), withSender) {
                if iszero(staticcall(gas(), withSender, 0x00, 0x00, 0x00, 0x20)) {
                    revert(0x00, 0x00) // For better gas estimation.
                }
            }
            result := mload(0x00)
        }
    }

    /**
     * @dev Returns the caller of `aggregateWithSender` on `MULTICALLER_WITH_SENDER`,
     *      if the current context's `msg.sender` is `MULTICALLER_WITH_SENDER`.
     *      Returns the signer of `aggregateWithSigner` on `MULTICALLER_WITH_SIGNER`,
     *      if the current context's `msg.sender` is `MULTICALLER_WITH_SIGNER`.
     *      Otherwise, returns `msg.sender`.
     */
    function senderOrSigner() internal view returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, caller())
            let withSender := MULTICALLER_WITH_SENDER
            if eq(caller(), withSender) {
                if iszero(staticcall(gas(), withSender, 0x00, 0x00, 0x00, 0x20)) {
                    revert(0x00, 0x00) // For better gas estimation.
                }
            }
            let withSigner := MULTICALLER_WITH_SIGNER
            if eq(caller(), withSigner) {
                if iszero(staticcall(gas(), withSigner, 0x00, 0x00, 0x00, 0x20)) {
                    revert(0x00, 0x00) // For better gas estimation.
                }
            }
            result := mload(0x00)
        }
    }
}

File 6 of 12 : Ownable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Simple single owner authorization mixin.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)
///
/// @dev Note:
/// This implementation does NOT auto-initialize the owner to `msg.sender`.
/// You MUST call the `_initializeOwner` in the constructor / initializer.
///
/// While the ownable portion follows
/// [EIP-173](https://eips.ethereum.org/EIPS/eip-173) for compatibility,
/// the nomenclature for the 2-step ownership handover may be unique to this codebase.
abstract contract Ownable {
    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev The caller is not authorized to call the function.
    error Unauthorized();

    /// @dev The `newOwner` cannot be the zero address.
    error NewOwnerIsZeroAddress();

    /// @dev The `pendingOwner` does not have a valid handover request.
    error NoHandoverRequest();

    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                           EVENTS                           */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev The ownership is transferred from `oldOwner` to `newOwner`.
    /// This event is intentionally kept the same as OpenZeppelin's Ownable to be
    /// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173),
    /// despite it not being as lightweight as a single argument event.
    event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);

    /// @dev An ownership handover to `pendingOwner` has been requested.
    event OwnershipHandoverRequested(address indexed pendingOwner);

    /// @dev The ownership handover to `pendingOwner` has been canceled.
    event OwnershipHandoverCanceled(address indexed pendingOwner);

    /// @dev `keccak256(bytes("OwnershipTransferred(address,address)"))`.
    uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE =
        0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0;

    /// @dev `keccak256(bytes("OwnershipHandoverRequested(address)"))`.
    uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE =
        0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d;

    /// @dev `keccak256(bytes("OwnershipHandoverCanceled(address)"))`.
    uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE =
        0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92;

    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                          STORAGE                           */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev The owner slot is given by: `not(_OWNER_SLOT_NOT)`.
    /// It is intentionally chosen to be a high value
    /// to avoid collision with lower slots.
    /// The choice of manual storage layout is to enable compatibility
    /// with both regular and upgradeable contracts.
    uint256 private constant _OWNER_SLOT_NOT = 0x8b78c6d8;

    /// The ownership handover slot of `newOwner` is given by:
    /// ```
    ///     mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED))
    ///     let handoverSlot := keccak256(0x00, 0x20)
    /// ```
    /// It stores the expiry timestamp of the two-step ownership handover.
    uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1;

    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                     INTERNAL FUNCTIONS                     */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev Initializes the owner directly without authorization guard.
    /// This function must be called upon initialization,
    /// regardless of whether the contract is upgradeable or not.
    /// This is to enable generalization to both regular and upgradeable contracts,
    /// and to save gas in case the initial owner is not the caller.
    /// For performance reasons, this function will not check if there
    /// is an existing owner.
    function _initializeOwner(address newOwner) internal virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // Clean the upper 96 bits.
            newOwner := shr(96, shl(96, newOwner))
            // Store the new value.
            sstore(not(_OWNER_SLOT_NOT), newOwner)
            // Emit the {OwnershipTransferred} event.
            log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
        }
    }

    /// @dev Sets the owner directly without authorization guard.
    function _setOwner(address newOwner) internal virtual {
        /// @solidity memory-safe-assembly
        assembly {
            let ownerSlot := not(_OWNER_SLOT_NOT)
            // Clean the upper 96 bits.
            newOwner := shr(96, shl(96, newOwner))
            // Emit the {OwnershipTransferred} event.
            log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
            // Store the new value.
            sstore(ownerSlot, newOwner)
        }
    }

    /// @dev Throws if the sender is not the owner.
    function _checkOwner() internal view virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // If the caller is not the stored owner, revert.
            if iszero(eq(caller(), sload(not(_OWNER_SLOT_NOT)))) {
                mstore(0x00, 0x82b42900) // `Unauthorized()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Returns how long a two-step ownership handover is valid for in seconds.
    /// Override to return a different value if needed.
    /// Made internal to conserve bytecode. Wrap it in a public function if needed.
    function _ownershipHandoverValidFor() internal view virtual returns (uint64) {
        return 48 * 3600;
    }

    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                  PUBLIC UPDATE FUNCTIONS                   */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev Allows the owner to transfer the ownership to `newOwner`.
    function transferOwnership(address newOwner) public payable virtual onlyOwner {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(shl(96, newOwner)) {
                mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`.
                revert(0x1c, 0x04)
            }
        }
        _setOwner(newOwner);
    }

    /// @dev Allows the owner to renounce their ownership.
    function renounceOwnership() public payable virtual onlyOwner {
        _setOwner(address(0));
    }

    /// @dev Request a two-step ownership handover to the caller.
    /// The request will automatically expire in 48 hours (172800 seconds) by default.
    function requestOwnershipHandover() public payable virtual {
        unchecked {
            uint256 expires = block.timestamp + _ownershipHandoverValidFor();
            /// @solidity memory-safe-assembly
            assembly {
                // Compute and set the handover slot to `expires`.
                mstore(0x0c, _HANDOVER_SLOT_SEED)
                mstore(0x00, caller())
                sstore(keccak256(0x0c, 0x20), expires)
                // Emit the {OwnershipHandoverRequested} event.
                log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())
            }
        }
    }

    /// @dev Cancels the two-step ownership handover to the caller, if any.
    function cancelOwnershipHandover() public payable virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute and set the handover slot to 0.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, caller())
            sstore(keccak256(0x0c, 0x20), 0)
            // Emit the {OwnershipHandoverCanceled} event.
            log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller())
        }
    }

    /// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`.
    /// Reverts if there is no existing ownership handover requested by `pendingOwner`.
    function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute and set the handover slot to 0.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, pendingOwner)
            let handoverSlot := keccak256(0x0c, 0x20)
            // If the handover does not exist, or has expired.
            if gt(timestamp(), sload(handoverSlot)) {
                mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`.
                revert(0x1c, 0x04)
            }
            // Set the handover slot to 0.
            sstore(handoverSlot, 0)
        }
        _setOwner(pendingOwner);
    }

    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                   PUBLIC READ FUNCTIONS                    */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev Returns the owner of the contract.
    function owner() public view virtual returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := sload(not(_OWNER_SLOT_NOT))
        }
    }

    /// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`.
    function ownershipHandoverExpiresAt(address pendingOwner)
        public
        view
        virtual
        returns (uint256 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute the handover slot.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, pendingOwner)
            // Load the handover slot.
            result := sload(keccak256(0x0c, 0x20))
        }
    }

    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                         MODIFIERS                          */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev Marks a function as only callable by the owner.
    modifier onlyOwner() virtual {
        _checkOwner();
        _;
    }
}

File 7 of 12 : EIP712.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Contract for EIP-712 typed structured data hashing and signing.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/EIP712.sol)
/// @author Modified from Solbase (https://github.com/Sol-DAO/solbase/blob/main/src/utils/EIP712.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/EIP712.sol)
///
/// @dev Note, this implementation:
/// - Uses `address(this)` for the `verifyingContract` field.
/// - Does NOT use the optional EIP-712 salt.
/// - Does NOT use any EIP-712 extensions.
/// This is for simplicity and to save gas.
/// If you need to customize, please fork / modify accordingly.
abstract contract EIP712 {
    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                  CONSTANTS AND IMMUTABLES                  */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev `keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")`.
    bytes32 internal constant _DOMAIN_TYPEHASH =
        0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;

    address private immutable _cachedThis;
    uint256 private immutable _cachedChainId;
    bytes32 private immutable _cachedNameHash;
    bytes32 private immutable _cachedVersionHash;
    bytes32 private immutable _cachedDomainSeparator;

    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                        CONSTRUCTOR                         */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev Cache the hashes for cheaper runtime gas costs.
    /// In the case of upgradeable contracts (i.e. proxies),
    /// or if the chain id changes due to a hard fork,
    /// the domain separator will be seamlessly calculated on-the-fly.
    constructor() {
        _cachedThis = address(this);
        _cachedChainId = block.chainid;

        string memory name;
        string memory version;
        if (!_domainNameAndVersionMayChange()) (name, version) = _domainNameAndVersion();
        bytes32 nameHash = _domainNameAndVersionMayChange() ? bytes32(0) : keccak256(bytes(name));
        bytes32 versionHash =
            _domainNameAndVersionMayChange() ? bytes32(0) : keccak256(bytes(version));
        _cachedNameHash = nameHash;
        _cachedVersionHash = versionHash;

        bytes32 separator;
        if (!_domainNameAndVersionMayChange()) {
            /// @solidity memory-safe-assembly
            assembly {
                let m := mload(0x40) // Load the free memory pointer.
                mstore(m, _DOMAIN_TYPEHASH)
                mstore(add(m, 0x20), nameHash)
                mstore(add(m, 0x40), versionHash)
                mstore(add(m, 0x60), chainid())
                mstore(add(m, 0x80), address())
                separator := keccak256(m, 0xa0)
            }
        }
        _cachedDomainSeparator = separator;
    }

    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                   FUNCTIONS TO OVERRIDE                    */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev Please override this function to return the domain name and version.
    /// ```
    ///     function _domainNameAndVersion()
    ///         internal
    ///         pure
    ///         virtual
    ///         returns (string memory name, string memory version)
    ///     {
    ///         name = "Solady";
    ///         version = "1";
    ///     }
    /// ```
    ///
    /// Note: If the returned result may change after the contract has been deployed,
    /// you must override `_domainNameAndVersionMayChange()` to return true.
    function _domainNameAndVersion()
        internal
        view
        virtual
        returns (string memory name, string memory version);

    /// @dev Returns if `_domainNameAndVersion()` may change
    /// after the contract has been deployed (i.e. after the constructor).
    /// Default: false.
    function _domainNameAndVersionMayChange() internal pure virtual returns (bool result) {}

    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                     HASHING OPERATIONS                     */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev Returns the EIP-712 domain separator.
    function _domainSeparator() internal view virtual returns (bytes32 separator) {
        if (_domainNameAndVersionMayChange()) {
            separator = _buildDomainSeparator();
        } else {
            separator = _cachedDomainSeparator;
            if (_cachedDomainSeparatorInvalidated()) separator = _buildDomainSeparator();
        }
    }

    /// @dev Returns the hash of the fully encoded EIP-712 message for this domain,
    /// given `structHash`, as defined in
    /// https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct.
    ///
    /// The hash can be used together with {ECDSA-recover} to obtain the signer of a message:
    /// ```
    ///     bytes32 digest = _hashTypedData(keccak256(abi.encode(
    ///         keccak256("Mail(address to,string contents)"),
    ///         mailTo,
    ///         keccak256(bytes(mailContents))
    ///     )));
    ///     address signer = ECDSA.recover(digest, signature);
    /// ```
    function _hashTypedData(bytes32 structHash) internal view virtual returns (bytes32 digest) {
        bytes32 separator;
        if (_domainNameAndVersionMayChange()) {
            separator = _buildDomainSeparator();
        } else {
            separator = _cachedDomainSeparator;
            if (_cachedDomainSeparatorInvalidated()) separator = _buildDomainSeparator();
        }
        /// @solidity memory-safe-assembly
        assembly {
            // Compute the digest.
            mstore(0x00, 0x1901000000000000) // Store "\x19\x01".
            mstore(0x1a, separator) // Store the domain separator.
            mstore(0x3a, structHash) // Store the struct hash.
            digest := keccak256(0x18, 0x42)
            // Restore the part of the free memory slot that was overwritten.
            mstore(0x3a, 0)
        }
    }

    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                    EIP-5267 OPERATIONS                     */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev See: https://eips.ethereum.org/EIPS/eip-5267
    function eip712Domain()
        public
        view
        virtual
        returns (
            bytes1 fields,
            string memory name,
            string memory version,
            uint256 chainId,
            address verifyingContract,
            bytes32 salt,
            uint256[] memory extensions
        )
    {
        fields = hex"0f"; // `0b01111`.
        (name, version) = _domainNameAndVersion();
        chainId = block.chainid;
        verifyingContract = address(this);
        salt = salt; // `bytes32(0)`.
        extensions = extensions; // `new uint256[](0)`.
    }

    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                      PRIVATE HELPERS                       */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev Returns the EIP-712 domain separator.
    function _buildDomainSeparator() private view returns (bytes32 separator) {
        bytes32 nameHash;
        bytes32 versionHash;
        if (_domainNameAndVersionMayChange()) {
            (string memory name, string memory version) = _domainNameAndVersion();
            nameHash = keccak256(bytes(name));
            versionHash = keccak256(bytes(version));
        } else {
            nameHash = _cachedNameHash;
            versionHash = _cachedVersionHash;
        }
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Load the free memory pointer.
            mstore(m, _DOMAIN_TYPEHASH)
            mstore(add(m, 0x20), nameHash)
            mstore(add(m, 0x40), versionHash)
            mstore(add(m, 0x60), chainid())
            mstore(add(m, 0x80), address())
            separator := keccak256(m, 0xa0)
        }
    }

    /// @dev Returns if the cached domain separator has been invalidated.
    function _cachedDomainSeparatorInvalidated() private view returns (bool result) {
        uint256 cachedChainId = _cachedChainId;
        address cachedThis = _cachedThis;
        /// @solidity memory-safe-assembly
        assembly {
            result := iszero(and(eq(chainid(), cachedChainId), eq(address(), cachedThis)))
        }
    }
}

File 8 of 12 : LibZip.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Library for compressing and decompressing bytes.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibZip.sol)
/// @author Calldata compression by clabby (https://github.com/clabby/op-kompressor)
/// @author FastLZ by ariya (https://github.com/ariya/FastLZ)
///
/// @dev Note:
/// The accompanying solady.js library includes implementations of
/// FastLZ and calldata operations for convenience.
library LibZip {
    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                     FAST LZ OPERATIONS                     */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    // LZ77 implementation based on FastLZ.
    // Equivalent to level 1 compression and decompression at the following commit:
    // https://github.com/ariya/FastLZ/commit/344eb4025f9ae866ebf7a2ec48850f7113a97a42
    // Decompression is backwards compatible.

    /// @dev Returns the compressed `data`.
    function flzCompress(bytes memory data) internal pure returns (bytes memory result) {
        /// @solidity memory-safe-assembly
        assembly {
            function ms8(d_, v_) -> _d {
                mstore8(d_, v_)
                _d := add(d_, 1)
            }
            function u24(p_) -> _u {
                let w := mload(p_)
                _u := or(shl(16, byte(2, w)), or(shl(8, byte(1, w)), byte(0, w)))
            }
            function cmp(p_, q_, e_) -> _l {
                for { e_ := sub(e_, q_) } lt(_l, e_) { _l := add(_l, 1) } {
                    e_ := mul(iszero(byte(0, xor(mload(add(p_, _l)), mload(add(q_, _l))))), e_)
                }
            }
            function literals(runs_, src_, dest_) -> _o {
                for { _o := dest_ } iszero(lt(runs_, 0x20)) { runs_ := sub(runs_, 0x20) } {
                    mstore(ms8(_o, 31), mload(src_))
                    _o := add(_o, 0x21)
                    src_ := add(src_, 0x20)
                }
                if iszero(runs_) { leave }
                mstore(ms8(_o, sub(runs_, 1)), mload(src_))
                _o := add(1, add(_o, runs_))
            }
            function match(l_, d_, o_) -> _o {
                for { d_ := sub(d_, 1) } iszero(lt(l_, 263)) { l_ := sub(l_, 262) } {
                    o_ := ms8(ms8(ms8(o_, add(224, shr(8, d_))), 253), and(0xff, d_))
                }
                if iszero(lt(l_, 7)) {
                    _o := ms8(ms8(ms8(o_, add(224, shr(8, d_))), sub(l_, 7)), and(0xff, d_))
                    leave
                }
                _o := ms8(ms8(o_, add(shl(5, l_), shr(8, d_))), and(0xff, d_))
            }
            function setHash(i_, v_) {
                let p := add(mload(0x40), shl(2, i_))
                mstore(p, xor(mload(p), shl(224, xor(shr(224, mload(p)), v_))))
            }
            function getHash(i_) -> _h {
                _h := shr(224, mload(add(mload(0x40), shl(2, i_))))
            }
            function hash(v_) -> _r {
                _r := and(shr(19, mul(2654435769, v_)), 0x1fff)
            }
            function setNextHash(ip_, ipStart_) -> _ip {
                setHash(hash(u24(ip_)), sub(ip_, ipStart_))
                _ip := add(ip_, 1)
            }
            codecopy(mload(0x40), codesize(), 0x8000) // Zeroize the hashmap.
            let op := add(mload(0x40), 0x8000)
            let a := add(data, 0x20)
            let ipStart := a
            let ipLimit := sub(add(ipStart, mload(data)), 13)
            for { let ip := add(2, a) } lt(ip, ipLimit) {} {
                let r := 0
                let d := 0
                for {} 1 {} {
                    let s := u24(ip)
                    let h := hash(s)
                    r := add(ipStart, getHash(h))
                    setHash(h, sub(ip, ipStart))
                    d := sub(ip, r)
                    if iszero(lt(ip, ipLimit)) { break }
                    ip := add(ip, 1)
                    if iszero(gt(d, 0x1fff)) { if eq(s, u24(r)) { break } }
                }
                if iszero(lt(ip, ipLimit)) { break }
                ip := sub(ip, 1)
                if gt(ip, a) { op := literals(sub(ip, a), a, op) }
                let l := cmp(add(r, 3), add(ip, 3), add(ipLimit, 9))
                op := match(l, d, op)
                ip := setNextHash(setNextHash(add(ip, l), ipStart), ipStart)
                a := ip
            }
            op := literals(sub(add(ipStart, mload(data)), a), a, op)
            result := mload(0x40)
            let t := add(result, 0x8000)
            let n := sub(op, t)
            mstore(result, n) // Store the length.
            // Copy the result to compact the memory, overwriting the hashmap.
            let o := add(result, 0x20)
            for { let i } lt(i, n) { i := add(i, 0x20) } { mstore(add(o, i), mload(add(t, i))) }
            mstore(add(o, n), 0) // Zeroize the slot after the string.
            mstore(0x40, add(add(o, n), 0x20)) // Allocate the memory.
        }
    }

    /// @dev Returns the decompressed `data`.
    function flzDecompress(bytes memory data) internal pure returns (bytes memory result) {
        /// @solidity memory-safe-assembly
        assembly {
            let n := 0
            let end := add(add(data, 0x20), mload(data))
            result := mload(0x40)
            let op := add(result, 0x20)
            for { data := add(data, 0x20) } lt(data, end) {} {
                let w := mload(data)
                let c := byte(0, w)
                let t := shr(5, c)
                if iszero(t) {
                    mstore(add(op, n), mload(add(data, 1)))
                    data := add(data, add(2, c))
                    n := add(n, add(1, c))
                    continue
                }
                let g := eq(t, 7)
                let l := add(2, xor(t, mul(g, xor(t, add(7, byte(1, w))))))
                for {
                    let s := add(add(shl(8, and(0x1f, c)), byte(add(1, g), w)), 1)
                    let r := add(op, sub(n, s))
                    let o := add(op, n)
                    let f := xor(s, mul(gt(s, 0x20), xor(s, 0x20)))
                    let j := 0
                } 1 {} {
                    mstore(add(o, j), mload(add(r, j)))
                    j := add(j, f)
                    if iszero(lt(j, l)) { break }
                }
                data := add(data, add(2, g))
                n := add(n, l)
            }
            mstore(result, n) // Store the length.
            let o := add(add(result, 0x20), n)
            mstore(o, 0) // Zeroize the slot after the string.
            mstore(0x40, add(o, 0x20)) // Allocate the memory.
        }
    }

    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                    CALLDATA OPERATIONS                     */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    // Calldata compression and decompression using selective run length encoding:
    // - Sequences of 0x00 (up to 128 consecutive).
    // - Sequences of 0xff (up to 32 consecutive).
    //
    // A run length encoded block consists of two bytes:
    // (0) 0x00
    // (1) A control byte with the following bit layout:
    //     - [7]     `0: 0x00, 1: 0xff`.
    //     - [0..6]  `runLength - 1`.
    //
    // The first 4 bytes are bitwise negated so that the compressed calldata
    // can be dispatched into the `fallback` and `receive` functions.

    /// @dev Returns the compressed `data`.
    function cdCompress(bytes memory data) internal pure returns (bytes memory result) {
        /// @solidity memory-safe-assembly
        assembly {
            function rle(v_, o_, d_) -> _o, _d {
                mstore(o_, shl(240, or(and(0xff, add(d_, 0xff)), and(0x80, v_))))
                _o := add(o_, 2)
            }
            result := mload(0x40)
            let o := add(result, 0x20)
            let z := 0 // Number of consecutive 0x00.
            let y := 0 // Number of consecutive 0xff.
            for { let end := add(data, mload(data)) } iszero(eq(data, end)) {} {
                data := add(data, 1)
                let c := byte(31, mload(data))
                if iszero(c) {
                    if y { o, y := rle(0xff, o, y) }
                    z := add(z, 1)
                    if eq(z, 0x80) { o, z := rle(0x00, o, 0x80) }
                    continue
                }
                if eq(c, 0xff) {
                    if z { o, z := rle(0x00, o, z) }
                    y := add(y, 1)
                    if eq(y, 0x20) { o, y := rle(0xff, o, 0x20) }
                    continue
                }
                if y { o, y := rle(0xff, o, y) }
                if z { o, z := rle(0x00, o, z) }
                mstore8(o, c)
                o := add(o, 1)
            }
            if y { o, y := rle(0xff, o, y) }
            if z { o, z := rle(0x00, o, z) }
            // Bitwise negate the first 4 bytes.
            mstore(add(result, 4), not(mload(add(result, 4))))
            mstore(result, sub(o, add(result, 0x20))) // Store the length.
            mstore(o, 0) // Zeroize the slot after the string.
            mstore(0x40, add(o, 0x20)) // Allocate the memory.
        }
    }

    /// @dev Returns the decompressed `data`.
    function cdDecompress(bytes memory data) internal pure returns (bytes memory result) {
        /// @solidity memory-safe-assembly
        assembly {
            if mload(data) {
                result := mload(0x40)
                let o := add(result, 0x20)
                let s := add(data, 4)
                let v := mload(s)
                let end := add(data, mload(data))
                mstore(s, not(v)) // Bitwise negate the first 4 bytes.
                for {} lt(data, end) {} {
                    data := add(data, 1)
                    let c := byte(31, mload(data))
                    if iszero(c) {
                        data := add(data, 1)
                        let d := byte(31, mload(data))
                        // Fill with either 0xff or 0x00.
                        mstore(o, not(0))
                        if iszero(gt(d, 0x7f)) { codecopy(o, codesize(), add(d, 1)) }
                        o := add(o, add(and(d, 0x7f), 1))
                        continue
                    }
                    mstore8(o, c)
                    o := add(o, 1)
                }
                mstore(s, v) // Restore the first 4 bytes.
                mstore(result, sub(o, add(result, 0x20))) // Store the length.
                mstore(o, 0) // Zeroize the slot after the string.
                mstore(0x40, add(o, 0x20)) // Allocate the memory.
            }
        }
    }

    /// @dev To be called in the `receive` and `fallback` functions.
    /// ```
    ///     receive() external payable { LibZip.cdFallback(); }
    ///     fallback() external payable { LibZip.cdFallback(); }
    /// ```
    /// For efficiency, this function will directly return the results, terminating the context.
    /// If called internally, it must be called at the end of the function.
    function cdFallback() internal {
        assembly {
            if iszero(calldatasize()) { return(calldatasize(), calldatasize()) }
            let o := 0
            let f := not(3) // For negating the first 4 bytes.
            for { let i := 0 } lt(i, calldatasize()) {} {
                let c := byte(0, xor(add(i, f), calldataload(i)))
                i := add(i, 1)
                if iszero(c) {
                    let d := byte(0, xor(add(i, f), calldataload(i)))
                    i := add(i, 1)
                    // Fill with either 0xff or 0x00.
                    mstore(o, not(0))
                    if iszero(gt(d, 0x7f)) { codecopy(o, codesize(), add(d, 1)) }
                    o := add(o, add(and(d, 0x7f), 1))
                    continue
                }
                mstore8(o, c)
                o := add(o, 1)
            }
            let success := delegatecall(gas(), address(), 0x00, o, 0x00, 0x00)
            returndatacopy(0x00, 0x00, returndatasize())
            if iszero(success) { revert(0x00, returndatasize()) }
            return(0x00, returndatasize())
        }
    }
}

File 9 of 12 : LibBitmap.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import {LibBit} from "./LibBit.sol";

/// @notice Library for storage of packed unsigned booleans.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibBitmap.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibBitmap.sol)
/// @author Modified from Solidity-Bits (https://github.com/estarriolvetch/solidity-bits/blob/main/contracts/BitMaps.sol)
library LibBitmap {
    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                         CONSTANTS                          */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev The constant returned when a bitmap scan does not find a result.
    uint256 internal constant NOT_FOUND = type(uint256).max;

    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                          STRUCTS                           */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev A bitmap in storage.
    struct Bitmap {
        mapping(uint256 => uint256) map;
    }

    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                         OPERATIONS                         */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev Returns the boolean value of the bit at `index` in `bitmap`.
    function get(Bitmap storage bitmap, uint256 index) internal view returns (bool isSet) {
        // It is better to set `isSet` to either 0 or 1, than zero vs non-zero.
        // Both cost the same amount of gas, but the former allows the returned value
        // to be reused without cleaning the upper bits.
        uint256 b = (bitmap.map[index >> 8] >> (index & 0xff)) & 1;
        /// @solidity memory-safe-assembly
        assembly {
            isSet := b
        }
    }

    /// @dev Updates the bit at `index` in `bitmap` to true.
    function set(Bitmap storage bitmap, uint256 index) internal {
        bitmap.map[index >> 8] |= (1 << (index & 0xff));
    }

    /// @dev Updates the bit at `index` in `bitmap` to false.
    function unset(Bitmap storage bitmap, uint256 index) internal {
        bitmap.map[index >> 8] &= ~(1 << (index & 0xff));
    }

    /// @dev Flips the bit at `index` in `bitmap`.
    /// Returns the boolean result of the flipped bit.
    function toggle(Bitmap storage bitmap, uint256 index) internal returns (bool newIsSet) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, shr(8, index))
            mstore(0x20, bitmap.slot)
            let storageSlot := keccak256(0x00, 0x40)
            let shift := and(index, 0xff)
            let storageValue := sload(storageSlot)

            let mask := shl(shift, 1)
            storageValue := xor(storageValue, mask)
            // It makes sense to return the `newIsSet`,
            // as it allow us to skip an additional warm `sload`,
            // and it costs minimal gas (about 15),
            // which may be optimized away if the returned value is unused.
            newIsSet := iszero(iszero(and(storageValue, mask)))
            sstore(storageSlot, storageValue)
        }
    }

    /// @dev Updates the bit at `index` in `bitmap` to `shouldSet`.
    function setTo(Bitmap storage bitmap, uint256 index, bool shouldSet) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x20, bitmap.slot)
            mstore(0x00, shr(8, index))
            let storageSlot := keccak256(0x00, 0x40)
            let storageValue := sload(storageSlot)
            let shift := and(index, 0xff)

            sstore(
                storageSlot,
                // Unsets the bit at `shift` via `and`, then sets its new value via `or`.
                or(and(storageValue, not(shl(shift, 1))), shl(shift, iszero(iszero(shouldSet))))
            )
        }
    }

    /// @dev Consecutively sets `amount` of bits starting from the bit at `start`.
    function setBatch(Bitmap storage bitmap, uint256 start, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            let max := not(0)
            let shift := and(start, 0xff)
            mstore(0x20, bitmap.slot)
            mstore(0x00, shr(8, start))
            if iszero(lt(add(shift, amount), 257)) {
                let storageSlot := keccak256(0x00, 0x40)
                sstore(storageSlot, or(sload(storageSlot), shl(shift, max)))
                let bucket := add(mload(0x00), 1)
                let bucketEnd := add(mload(0x00), shr(8, add(amount, shift)))
                amount := and(add(amount, shift), 0xff)
                shift := 0
                for {} iszero(eq(bucket, bucketEnd)) { bucket := add(bucket, 1) } {
                    mstore(0x00, bucket)
                    sstore(keccak256(0x00, 0x40), max)
                }
                mstore(0x00, bucket)
            }
            let storageSlot := keccak256(0x00, 0x40)
            sstore(storageSlot, or(sload(storageSlot), shl(shift, shr(sub(256, amount), max))))
        }
    }

    /// @dev Consecutively unsets `amount` of bits starting from the bit at `start`.
    function unsetBatch(Bitmap storage bitmap, uint256 start, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            let shift := and(start, 0xff)
            mstore(0x20, bitmap.slot)
            mstore(0x00, shr(8, start))
            if iszero(lt(add(shift, amount), 257)) {
                let storageSlot := keccak256(0x00, 0x40)
                sstore(storageSlot, and(sload(storageSlot), not(shl(shift, not(0)))))
                let bucket := add(mload(0x00), 1)
                let bucketEnd := add(mload(0x00), shr(8, add(amount, shift)))
                amount := and(add(amount, shift), 0xff)
                shift := 0
                for {} iszero(eq(bucket, bucketEnd)) { bucket := add(bucket, 1) } {
                    mstore(0x00, bucket)
                    sstore(keccak256(0x00, 0x40), 0)
                }
                mstore(0x00, bucket)
            }
            let storageSlot := keccak256(0x00, 0x40)
            sstore(
                storageSlot, and(sload(storageSlot), not(shl(shift, shr(sub(256, amount), not(0)))))
            )
        }
    }

    /// @dev Returns number of set bits within a range by
    /// scanning `amount` of bits starting from the bit at `start`.
    function popCount(Bitmap storage bitmap, uint256 start, uint256 amount)
        internal
        view
        returns (uint256 count)
    {
        unchecked {
            uint256 bucket = start >> 8;
            uint256 shift = start & 0xff;
            if (!(amount + shift < 257)) {
                count = LibBit.popCount(bitmap.map[bucket] >> shift);
                uint256 bucketEnd = bucket + ((amount + shift) >> 8);
                amount = (amount + shift) & 0xff;
                shift = 0;
                for (++bucket; bucket != bucketEnd; ++bucket) {
                    count += LibBit.popCount(bitmap.map[bucket]);
                }
            }
            count += LibBit.popCount((bitmap.map[bucket] >> shift) << (256 - amount));
        }
    }

    /// @dev Returns the index of the most significant set bit before the bit at `before`.
    /// If no set bit is found, returns `NOT_FOUND`.
    function findLastSet(Bitmap storage bitmap, uint256 before)
        internal
        view
        returns (uint256 setBitIndex)
    {
        uint256 bucket;
        uint256 bucketBits;
        /// @solidity memory-safe-assembly
        assembly {
            setBitIndex := not(0)
            bucket := shr(8, before)
            mstore(0x00, bucket)
            mstore(0x20, bitmap.slot)
            let offset := and(0xff, not(before)) // `256 - (255 & before) - 1`.
            bucketBits := shr(offset, shl(offset, sload(keccak256(0x00, 0x40))))
            if iszero(bucketBits) {
                for {} bucket {} {
                    bucket := add(bucket, setBitIndex) // `sub(bucket, 1)`.
                    mstore(0x00, bucket)
                    bucketBits := sload(keccak256(0x00, 0x40))
                    if bucketBits { break }
                }
            }
        }
        if (bucketBits != 0) {
            setBitIndex = (bucket << 8) | LibBit.fls(bucketBits);
            /// @solidity memory-safe-assembly
            assembly {
                setBitIndex := or(setBitIndex, sub(0, gt(setBitIndex, before)))
            }
        }
    }
}

File 10 of 12 : SafeTransferLib.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
///
/// @dev Note:
/// - For ETH transfers, please use `forceSafeTransferETH` for DoS protection.
/// - For ERC20s, this implementation won't check that a token has code,
///   responsibility is delegated to the caller.
library SafeTransferLib {
    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev The ETH transfer has failed.
    error ETHTransferFailed();

    /// @dev The ERC20 `transferFrom` has failed.
    error TransferFromFailed();

    /// @dev The ERC20 `transfer` has failed.
    error TransferFailed();

    /// @dev The ERC20 `approve` has failed.
    error ApproveFailed();

    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                         CONSTANTS                          */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev Suggested gas stipend for contract receiving ETH that disallows any storage writes.
    uint256 internal constant GAS_STIPEND_NO_STORAGE_WRITES = 2300;

    /// @dev Suggested gas stipend for contract receiving ETH to perform a few
    /// storage reads and writes, but low enough to prevent griefing.
    uint256 internal constant GAS_STIPEND_NO_GRIEF = 100000;

    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                       ETH OPERATIONS                       */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    // If the ETH transfer MUST succeed with a reasonable gas budget, use the force variants.
    //
    // The regular variants:
    // - Forwards all remaining gas to the target.
    // - Reverts if the target reverts.
    // - Reverts if the current contract has insufficient balance.
    //
    // The force variants:
    // - Forwards with an optional gas stipend
    //   (defaults to `GAS_STIPEND_NO_GRIEF`, which is sufficient for most cases).
    // - If the target reverts, or if the gas stipend is exhausted,
    //   creates a temporary contract to force send the ETH via `SELFDESTRUCT`.
    //   Future compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758.
    // - Reverts if the current contract has insufficient balance.
    //
    // The try variants:
    // - Forwards with a mandatory gas stipend.
    // - Instead of reverting, returns whether the transfer succeeded.

    /// @dev Sends `amount` (in wei) ETH to `to`.
    function safeTransferETH(address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(call(gas(), to, amount, gas(), 0x00, gas(), 0x00)) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Sends all the ETH in the current contract to `to`.
    function safeTransferAllETH(address to) internal {
        /// @solidity memory-safe-assembly
        assembly {
            // Transfer all the ETH and check if it succeeded or not.
            if iszero(call(gas(), to, selfbalance(), gas(), 0x00, gas(), 0x00)) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
    function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if lt(selfbalance(), amount) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
            if iszero(call(gasStipend, to, amount, gas(), 0x00, gas(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(amount, 0x0b, 0x16)) {
                    returndatacopy(gas(), returndatasize(), shr(20, gas())) // For gas estimation.
                }
            }
        }
    }

    /// @dev Force sends all the ETH in the current contract to `to`, with a `gasStipend`.
    function forceSafeTransferAllETH(address to, uint256 gasStipend) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(call(gasStipend, to, selfbalance(), gas(), 0x00, gas(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(selfbalance(), 0x0b, 0x16)) {
                    returndatacopy(gas(), returndatasize(), shr(20, gas())) // For gas estimation.
                }
            }
        }
    }

    /// @dev Force sends `amount` (in wei) ETH to `to`, with `GAS_STIPEND_NO_GRIEF`.
    function forceSafeTransferETH(address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if lt(selfbalance(), amount) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
            if iszero(call(GAS_STIPEND_NO_GRIEF, to, amount, gas(), 0x00, gas(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(amount, 0x0b, 0x16)) {
                    returndatacopy(gas(), returndatasize(), shr(20, gas())) // For gas estimation.
                }
            }
        }
    }

    /// @dev Force sends all the ETH in the current contract to `to`, with `GAS_STIPEND_NO_GRIEF`.
    function forceSafeTransferAllETH(address to) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(call(GAS_STIPEND_NO_GRIEF, to, selfbalance(), gas(), 0x00, gas(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(selfbalance(), 0x0b, 0x16)) {
                    returndatacopy(gas(), returndatasize(), shr(20, gas())) // For gas estimation.
                }
            }
        }
    }

    /// @dev Sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
    function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend)
        internal
        returns (bool success)
    {
        /// @solidity memory-safe-assembly
        assembly {
            success := call(gasStipend, to, amount, gas(), 0x00, gas(), 0x00)
        }
    }

    /// @dev Sends all the ETH in the current contract to `to`, with a `gasStipend`.
    function trySafeTransferAllETH(address to, uint256 gasStipend)
        internal
        returns (bool success)
    {
        /// @solidity memory-safe-assembly
        assembly {
            success := call(gasStipend, to, selfbalance(), gas(), 0x00, gas(), 0x00)
        }
    }

    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                      ERC20 OPERATIONS                      */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
    /// Reverts upon failure.
    ///
    /// The `from` account must have at least `amount` approved for
    /// the current contract to manage.
    function safeTransferFrom(address token, address from, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.
            mstore(0x60, amount) // Store the `amount` argument.
            mstore(0x40, to) // Store the `to` argument.
            mstore(0x2c, shl(96, from)) // Store the `from` argument.
            mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x60, 0) // Restore the zero slot to zero.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /// @dev Sends all of ERC20 `token` from `from` to `to`.
    /// Reverts upon failure.
    ///
    /// The `from` account must have their entire balance approved for
    /// the current contract to manage.
    function safeTransferAllFrom(address token, address from, address to)
        internal
        returns (uint256 amount)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.
            mstore(0x40, to) // Store the `to` argument.
            mstore(0x2c, shl(96, from)) // Store the `from` argument.
            mstore(0x0c, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
            // Read the balance, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                    staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20)
                )
            ) {
                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x00, 0x23b872dd) // `transferFrom(address,address,uint256)`.
            amount := mload(0x60) // The `amount` is already at 0x60. We'll need to return it.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x60, 0) // Restore the zero slot to zero.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`.
    /// Reverts upon failure.
    function safeTransfer(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Sends all of ERC20 `token` from the current contract to `to`.
    /// Reverts upon failure.
    function safeTransferAll(address token, address to) internal returns (uint256 amount) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`.
            mstore(0x20, address()) // Store the address of the current contract.
            // Read the balance, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                    staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20)
                )
            ) {
                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x14, to) // Store the `to` argument.
            amount := mload(0x34) // The `amount` is already at 0x34. We'll need to return it.
            mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
    /// Reverts upon failure.
    function safeApprove(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
            // Perform the approval, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
    /// If the initial attempt to approve fails, attempts to reset the approved amount to zero,
    /// then retries the approval again (some tokens, e.g. USDT, requires this).
    /// Reverts upon failure.
    function safeApproveWithRetry(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
            // Perform the approval, retrying upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x34, 0) // Store 0 for the `amount`.
                mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
                pop(call(gas(), token, 0, 0x10, 0x44, 0x00, 0x00)) // Reset the approval.
                mstore(0x34, amount) // Store back the original `amount`.
                // Retry the approval, reverting upon failure.
                if iszero(
                    and(
                        or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                        call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                    )
                ) {
                    mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.
                    revert(0x1c, 0x04)
                }
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Returns the amount of ERC20 `token` owned by `account`.
    /// Returns zero if the `token` does not exist.
    function balanceOf(address token, address account) internal view returns (uint256 amount) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, account) // Store the `account` argument.
            mstore(0x00, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
            amount :=
                mul(
                    mload(0x20),
                    and( // The arguments of `and` are evaluated from right to left.
                        gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                        staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20)
                    )
                )
        }
    }
}

File 11 of 12 : SignatureCheckerLib.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Signature verification helper that supports both ECDSA signatures from EOAs
/// and ERC1271 signatures from smart contract wallets like Argent and Gnosis safe.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SignatureCheckerLib.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/SignatureChecker.sol)
///
/// @dev Note:
/// - The signature checking functions use the ecrecover precompile (0x1).
/// - The `bytes memory signature` variants use the identity precompile (0x4)
///   to copy memory internally.
/// - Unlike ECDSA signatures, contract signatures are revocable.
///
/// WARNING! Do NOT use signatures as unique identifiers.
/// Please use EIP712 with a nonce included in the digest to prevent replay attacks.
/// This implementation does NOT check if a signature is non-malleable.
library SignatureCheckerLib {
    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*               SIGNATURE CHECKING OPERATIONS                */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev Returns whether `signature` is valid for `signer` and `hash`.
    /// If `signer` is a smart contract, the signature is validated with ERC1271.
    /// Otherwise, the signature is validated with `ECDSA.recover`.
    function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature)
        internal
        view
        returns (bool isValid)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Clean the upper 96 bits of `signer` in case they are dirty.
            for { signer := shr(96, shl(96, signer)) } signer {} {
                let m := mload(0x40)
                if eq(mload(signature), 65) {
                    mstore(0x00, hash)
                    mstore(0x20, byte(0, mload(add(signature, 0x60)))) // `v`.
                    mstore(0x40, mload(add(signature, 0x20))) // `r`.
                    mstore(0x60, mload(add(signature, 0x40))) // `s`.
                    let t :=
                        staticcall(
                            gas(), // Amount of gas left for the transaction.
                            1, // Address of `ecrecover`.
                            0x00, // Start of input.
                            0x80, // Size of input.
                            0x01, // Start of output.
                            0x20 // Size of output.
                        )
                    // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
                    if iszero(or(iszero(returndatasize()), xor(signer, mload(t)))) {
                        isValid := 1
                        mstore(0x60, 0) // Restore the zero slot.
                        mstore(0x40, m) // Restore the free memory pointer.
                        break
                    }
                }
                mstore(0x60, 0) // Restore the zero slot.
                mstore(0x40, m) // Restore the free memory pointer.

                let f := shl(224, 0x1626ba7e)
                mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`.
                mstore(add(m, 0x04), hash)
                let d := add(m, 0x24)
                mstore(d, 0x40) // The offset of the `signature` in the calldata.
                // Copy the `signature` over.
                let n := add(0x20, mload(signature))
                pop(staticcall(gas(), 4, signature, n, add(m, 0x44), n))
                // forgefmt: disable-next-item
                isValid := and(
                    // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).
                    eq(mload(d), f),
                    // Whether the staticcall does not revert.
                    // This must be placed at the end of the `and` clause,
                    // as the arguments are evaluated from right to left.
                    staticcall(
                        gas(), // Remaining gas.
                        signer, // The `signer` address.
                        m, // Offset of calldata in memory.
                        add(returndatasize(), 0x44), // Length of calldata in memory.
                        d, // Offset of returndata.
                        0x20 // Length of returndata to write.
                    )
                )
                break
            }
        }
    }

    /// @dev Returns whether `signature` is valid for `signer` and `hash`.
    /// If `signer` is a smart contract, the signature is validated with ERC1271.
    /// Otherwise, the signature is validated with `ECDSA.recover`.
    function isValidSignatureNowCalldata(address signer, bytes32 hash, bytes calldata signature)
        internal
        view
        returns (bool isValid)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Clean the upper 96 bits of `signer` in case they are dirty.
            for { signer := shr(96, shl(96, signer)) } signer {} {
                let m := mload(0x40)
                if eq(signature.length, 65) {
                    mstore(0x00, hash)
                    mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40)))) // `v`.
                    calldatacopy(0x40, signature.offset, 0x40) // `r`, `s`.
                    let t :=
                        staticcall(
                            gas(), // Amount of gas left for the transaction.
                            1, // Address of `ecrecover`.
                            0x00, // Start of input.
                            0x80, // Size of input.
                            0x01, // Start of output.
                            0x20 // Size of output.
                        )
                    // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
                    if iszero(or(iszero(returndatasize()), xor(signer, mload(t)))) {
                        isValid := 1
                        mstore(0x60, 0) // Restore the zero slot.
                        mstore(0x40, m) // Restore the free memory pointer.
                        break
                    }
                }
                mstore(0x60, 0) // Restore the zero slot.
                mstore(0x40, m) // Restore the free memory pointer.

                let f := shl(224, 0x1626ba7e)
                mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`.
                mstore(add(m, 0x04), hash)
                let d := add(m, 0x24)
                mstore(d, 0x40) // The offset of the `signature` in the calldata.
                mstore(add(m, 0x44), signature.length)
                // Copy the `signature` over.
                calldatacopy(add(m, 0x64), signature.offset, signature.length)
                // forgefmt: disable-next-item
                isValid := and(
                    // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).
                    eq(mload(d), f),
                    // Whether the staticcall does not revert.
                    // This must be placed at the end of the `and` clause,
                    // as the arguments are evaluated from right to left.
                    staticcall(
                        gas(), // Remaining gas.
                        signer, // The `signer` address.
                        m, // Offset of calldata in memory.
                        add(signature.length, 0x64), // Length of calldata in memory.
                        d, // Offset of returndata.
                        0x20 // Length of returndata to write.
                    )
                )
                break
            }
        }
    }

    /// @dev Returns whether the signature (`r`, `vs`) is valid for `signer` and `hash`.
    /// If `signer` is a smart contract, the signature is validated with ERC1271.
    /// Otherwise, the signature is validated with `ECDSA.recover`.
    function isValidSignatureNow(address signer, bytes32 hash, bytes32 r, bytes32 vs)
        internal
        view
        returns (bool isValid)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Clean the upper 96 bits of `signer` in case they are dirty.
            for { signer := shr(96, shl(96, signer)) } signer {} {
                let m := mload(0x40)
                mstore(0x00, hash)
                mstore(0x20, add(shr(255, vs), 27)) // `v`.
                mstore(0x40, r) // `r`.
                mstore(0x60, shr(1, shl(1, vs))) // `s`.
                let t :=
                    staticcall(
                        gas(), // Amount of gas left for the transaction.
                        1, // Address of `ecrecover`.
                        0x00, // Start of input.
                        0x80, // Size of input.
                        0x01, // Start of output.
                        0x20 // Size of output.
                    )
                // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
                if iszero(or(iszero(returndatasize()), xor(signer, mload(t)))) {
                    isValid := 1
                    mstore(0x60, 0) // Restore the zero slot.
                    mstore(0x40, m) // Restore the free memory pointer.
                    break
                }

                let f := shl(224, 0x1626ba7e)
                mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`.
                mstore(add(m, 0x04), hash)
                let d := add(m, 0x24)
                mstore(d, 0x40) // The offset of the `signature` in the calldata.
                mstore(add(m, 0x44), 65) // Length of the signature.
                mstore(add(m, 0x64), r) // `r`.
                mstore(add(m, 0x84), mload(0x60)) // `s`.
                mstore8(add(m, 0xa4), mload(0x20)) // `v`.
                // forgefmt: disable-next-item
                isValid := and(
                    // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).
                    eq(mload(d), f),
                    // Whether the staticcall does not revert.
                    // This must be placed at the end of the `and` clause,
                    // as the arguments are evaluated from right to left.
                    staticcall(
                        gas(), // Remaining gas.
                        signer, // The `signer` address.
                        m, // Offset of calldata in memory.
                        0xa5, // Length of calldata in memory.
                        d, // Offset of returndata.
                        0x20 // Length of returndata to write.
                    )
                )
                mstore(0x60, 0) // Restore the zero slot.
                mstore(0x40, m) // Restore the free memory pointer.
                break
            }
        }
    }

    /// @dev Returns whether the signature (`v`, `r`, `s`) is valid for `signer` and `hash`.
    /// If `signer` is a smart contract, the signature is validated with ERC1271.
    /// Otherwise, the signature is validated with `ECDSA.recover`.
    function isValidSignatureNow(address signer, bytes32 hash, uint8 v, bytes32 r, bytes32 s)
        internal
        view
        returns (bool isValid)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Clean the upper 96 bits of `signer` in case they are dirty.
            for { signer := shr(96, shl(96, signer)) } signer {} {
                let m := mload(0x40)
                mstore(0x00, hash)
                mstore(0x20, and(v, 0xff)) // `v`.
                mstore(0x40, r) // `r`.
                mstore(0x60, s) // `s`.
                let t :=
                    staticcall(
                        gas(), // Amount of gas left for the transaction.
                        1, // Address of `ecrecover`.
                        0x00, // Start of input.
                        0x80, // Size of input.
                        0x01, // Start of output.
                        0x20 // Size of output.
                    )
                // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
                if iszero(or(iszero(returndatasize()), xor(signer, mload(t)))) {
                    isValid := 1
                    mstore(0x60, 0) // Restore the zero slot.
                    mstore(0x40, m) // Restore the free memory pointer.
                    break
                }

                let f := shl(224, 0x1626ba7e)
                mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`.
                mstore(add(m, 0x04), hash)
                let d := add(m, 0x24)
                mstore(d, 0x40) // The offset of the `signature` in the calldata.
                mstore(add(m, 0x44), 65) // Length of the signature.
                mstore(add(m, 0x64), r) // `r`.
                mstore(add(m, 0x84), s) // `s`.
                mstore8(add(m, 0xa4), v) // `v`.
                // forgefmt: disable-next-item
                isValid := and(
                    // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).
                    eq(mload(d), f),
                    // Whether the staticcall does not revert.
                    // This must be placed at the end of the `and` clause,
                    // as the arguments are evaluated from right to left.
                    staticcall(
                        gas(), // Remaining gas.
                        signer, // The `signer` address.
                        m, // Offset of calldata in memory.
                        0xa5, // Length of calldata in memory.
                        d, // Offset of returndata.
                        0x20 // Length of returndata to write.
                    )
                )
                mstore(0x60, 0) // Restore the zero slot.
                mstore(0x40, m) // Restore the free memory pointer.
                break
            }
        }
    }

    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                     ERC1271 OPERATIONS                     */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev Returns whether `signature` is valid for `hash`
    /// for an ERC1271 `signer` contract.
    function isValidERC1271SignatureNow(address signer, bytes32 hash, bytes memory signature)
        internal
        view
        returns (bool isValid)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            let f := shl(224, 0x1626ba7e)
            mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`.
            mstore(add(m, 0x04), hash)
            let d := add(m, 0x24)
            mstore(d, 0x40) // The offset of the `signature` in the calldata.
            // Copy the `signature` over.
            let n := add(0x20, mload(signature))
            pop(staticcall(gas(), 4, signature, n, add(m, 0x44), n))
            // forgefmt: disable-next-item
            isValid := and(
                // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).
                eq(mload(d), f),
                // Whether the staticcall does not revert.
                // This must be placed at the end of the `and` clause,
                // as the arguments are evaluated from right to left.
                staticcall(
                    gas(), // Remaining gas.
                    signer, // The `signer` address.
                    m, // Offset of calldata in memory.
                    add(returndatasize(), 0x44), // Length of calldata in memory.
                    d, // Offset of returndata.
                    0x20 // Length of returndata to write.
                )
            )
        }
    }

    /// @dev Returns whether `signature` is valid for `hash`
    /// for an ERC1271 `signer` contract.
    function isValidERC1271SignatureNowCalldata(
        address signer,
        bytes32 hash,
        bytes calldata signature
    ) internal view returns (bool isValid) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            let f := shl(224, 0x1626ba7e)
            mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`.
            mstore(add(m, 0x04), hash)
            let d := add(m, 0x24)
            mstore(d, 0x40) // The offset of the `signature` in the calldata.
            mstore(add(m, 0x44), signature.length)
            // Copy the `signature` over.
            calldatacopy(add(m, 0x64), signature.offset, signature.length)
            // forgefmt: disable-next-item
            isValid := and(
                // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).
                eq(mload(d), f),
                // Whether the staticcall does not revert.
                // This must be placed at the end of the `and` clause,
                // as the arguments are evaluated from right to left.
                staticcall(
                    gas(), // Remaining gas.
                    signer, // The `signer` address.
                    m, // Offset of calldata in memory.
                    add(signature.length, 0x64), // Length of calldata in memory.
                    d, // Offset of returndata.
                    0x20 // Length of returndata to write.
                )
            )
        }
    }

    /// @dev Returns whether the signature (`r`, `vs`) is valid for `hash`
    /// for an ERC1271 `signer` contract.
    function isValidERC1271SignatureNow(address signer, bytes32 hash, bytes32 r, bytes32 vs)
        internal
        view
        returns (bool isValid)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            let f := shl(224, 0x1626ba7e)
            mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`.
            mstore(add(m, 0x04), hash)
            let d := add(m, 0x24)
            mstore(d, 0x40) // The offset of the `signature` in the calldata.
            mstore(add(m, 0x44), 65) // Length of the signature.
            mstore(add(m, 0x64), r) // `r`.
            mstore(add(m, 0x84), shr(1, shl(1, vs))) // `s`.
            mstore8(add(m, 0xa4), add(shr(255, vs), 27)) // `v`.
            // forgefmt: disable-next-item
            isValid := and(
                // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).
                eq(mload(d), f),
                // Whether the staticcall does not revert.
                // This must be placed at the end of the `and` clause,
                // as the arguments are evaluated from right to left.
                staticcall(
                    gas(), // Remaining gas.
                    signer, // The `signer` address.
                    m, // Offset of calldata in memory.
                    0xa5, // Length of calldata in memory.
                    d, // Offset of returndata.
                    0x20 // Length of returndata to write.
                )
            )
        }
    }

    /// @dev Returns whether the signature (`v`, `r`, `s`) is valid for `hash`
    /// for an ERC1271 `signer` contract.
    function isValidERC1271SignatureNow(address signer, bytes32 hash, uint8 v, bytes32 r, bytes32 s)
        internal
        view
        returns (bool isValid)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            let f := shl(224, 0x1626ba7e)
            mstore(m, f) // `bytes4(keccak256("isValidSignature(bytes32,bytes)"))`.
            mstore(add(m, 0x04), hash)
            let d := add(m, 0x24)
            mstore(d, 0x40) // The offset of the `signature` in the calldata.
            mstore(add(m, 0x44), 65) // Length of the signature.
            mstore(add(m, 0x64), r) // `r`.
            mstore(add(m, 0x84), s) // `s`.
            mstore8(add(m, 0xa4), v) // `v`.
            // forgefmt: disable-next-item
            isValid := and(
                // Whether the returndata is the magic value `0x1626ba7e` (left-aligned).
                eq(mload(d), f),
                // Whether the staticcall does not revert.
                // This must be placed at the end of the `and` clause,
                // as the arguments are evaluated from right to left.
                staticcall(
                    gas(), // Remaining gas.
                    signer, // The `signer` address.
                    m, // Offset of calldata in memory.
                    0xa5, // Length of calldata in memory.
                    d, // Offset of returndata.
                    0x20 // Length of returndata to write.
                )
            )
        }
    }

    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                   EMPTY CALLDATA HELPERS                   */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev Returns an empty calldata bytes.
    function emptySignature() internal pure returns (bytes calldata signature) {
        /// @solidity memory-safe-assembly
        assembly {
            signature.length := 0
        }
    }
}

File 12 of 12 : LibBit.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Library for bit twiddling and boolean operations.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibBit.sol)
/// @author Inspired by (https://graphics.stanford.edu/~seander/bithacks.html)
library LibBit {
    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                  BIT TWIDDLING OPERATIONS                  */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    /// @dev Find last set.
    /// Returns the index of the most significant bit of `x`,
    /// counting from the least significant bit position.
    /// If `x` is zero, returns 256.
    function fls(uint256 x) internal pure returns (uint256 r) {
        /// @solidity memory-safe-assembly
        assembly {
            r := or(shl(8, iszero(x)), shl(7, lt(0xffffffffffffffffffffffffffffffff, x)))
            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
            r := or(r, shl(4, lt(0xffff, shr(r, x))))
            r := or(r, shl(3, lt(0xff, shr(r, x))))
            r := or(r, shl(2, lt(0xf, shr(r, x))))
            r := or(r, byte(shr(r, x), hex"00000101020202020303030303030303"))
        }
    }

    /// @dev Count leading zeros.
    /// Returns the number of zeros preceding the most significant one bit.
    /// If `x` is zero, returns 256.
    function clz(uint256 x) internal pure returns (uint256 r) {
        /// @solidity memory-safe-assembly
        assembly {
            r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
            r := or(r, shl(4, lt(0xffff, shr(r, x))))
            r := or(r, shl(3, lt(0xff, shr(r, x))))
            r := or(r, shl(2, lt(0xf, shr(r, x))))
            // forgefmt: disable-next-item
            r := add(iszero(x), xor(255,
                or(r, byte(shr(r, x), hex"00000101020202020303030303030303"))))
        }
    }

    /// @dev Find first set.
    /// Returns the index of the least significant bit of `x`,
    /// counting from the least significant bit position.
    /// If `x` is zero, returns 256.
    /// Equivalent to `ctz` (count trailing zeros), which gives
    /// the number of zeros following the least significant one bit.
    function ffs(uint256 x) internal pure returns (uint256 r) {
        /// @solidity memory-safe-assembly
        assembly {
            // Isolate the least significant bit.
            let b := and(x, add(not(x), 1))

            r := or(shl(8, iszero(x)), shl(7, lt(0xffffffffffffffffffffffffffffffff, b)))
            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, b))))
            r := or(r, shl(5, lt(0xffffffff, shr(r, b))))

            // For the remaining 32 bits, use a De Bruijn lookup.
            // forgefmt: disable-next-item
            r := or(r, byte(and(div(0xd76453e0, shr(r, b)), 0x1f),
                0x001f0d1e100c1d070f090b19131c1706010e11080a1a141802121b1503160405))
        }
    }

    /// @dev Returns the number of set bits in `x`.
    function popCount(uint256 x) internal pure returns (uint256 c) {
        /// @solidity memory-safe-assembly
        assembly {
            let max := not(0)
            let isMax := eq(x, max)
            x := sub(x, and(shr(1, x), div(max, 3)))
            x := add(and(x, div(max, 5)), and(shr(2, x), div(max, 5)))
            x := and(add(x, shr(4, x)), div(max, 17))
            c := or(shl(8, isMax), shr(248, mul(x, div(max, 255))))
        }
    }

    /// @dev Returns whether `x` is a power of 2.
    function isPo2(uint256 x) internal pure returns (bool result) {
        /// @solidity memory-safe-assembly
        assembly {
            // Equivalent to `x && !(x & (x - 1))`.
            result := iszero(add(and(x, sub(x, 1)), iszero(x)))
        }
    }

    /// @dev Returns `x` reversed at the bit level.
    function reverseBits(uint256 x) internal pure returns (uint256 r) {
        /// @solidity memory-safe-assembly
        assembly {
            // Computing masks on-the-fly reduces bytecode size by about 500 bytes.
            let m := not(0)
            r := x
            for { let s := 128 } 1 {} {
                m := xor(m, shl(s, m))
                r := or(and(shr(s, r), m), and(shl(s, r), not(m)))
                s := shr(1, s)
                if iszero(s) { break }
            }
        }
    }

    /// @dev Returns `x` reversed at the byte level.
    function reverseBytes(uint256 x) internal pure returns (uint256 r) {
        /// @solidity memory-safe-assembly
        assembly {
            // Computing masks on-the-fly reduces bytecode size by about 200 bytes.
            let m := not(0)
            r := x
            for { let s := 128 } 1 {} {
                m := xor(m, shl(s, m))
                r := or(and(shr(s, r), m), and(shl(s, r), not(m)))
                s := shr(1, s)
                if eq(s, 4) { break }
            }
        }
    }

    /*´:°â€¢.°+.*•´.*:Ëš.°*.˚•´.°:°â€¢.°â€¢.*•´.*:Ëš.°*.˚•´.°:°â€¢.°+.*•´.*:*/
    /*                     BOOLEAN OPERATIONS                     */
    /*.•°:°.´+Ëš.*°.Ëš:*.´â€¢*.+°.•°:´*.´â€¢*.•°.•°:°.´:•˚°.*°.Ëš:*.´+°.•*/

    // A Solidity bool on the stack or memory is represented as a 256-bit word.
    // Non-zero values are true, zero is false.
    // A clean bool is either 0 (false) or 1 (true) under the hood.
    // Usually, if not always, the bool result of a regular Solidity expression,
    // or the argument of a public/external function will be a clean bool.
    // You can usually use the raw variants for more performance.
    // If uncertain, test (best with exact compiler settings).
    // Or use the non-raw variants (compiler can sometimes optimize out the double `iszero`s).

    /// @dev Returns `x & y`. Inputs must be clean.
    function rawAnd(bool x, bool y) internal pure returns (bool z) {
        /// @solidity memory-safe-assembly
        assembly {
            z := and(x, y)
        }
    }

    /// @dev Returns `x & y`.
    function and(bool x, bool y) internal pure returns (bool z) {
        /// @solidity memory-safe-assembly
        assembly {
            z := and(iszero(iszero(x)), iszero(iszero(y)))
        }
    }

    /// @dev Returns `x | y`. Inputs must be clean.
    function rawOr(bool x, bool y) internal pure returns (bool z) {
        /// @solidity memory-safe-assembly
        assembly {
            z := or(x, y)
        }
    }

    /// @dev Returns `x | y`.
    function or(bool x, bool y) internal pure returns (bool z) {
        /// @solidity memory-safe-assembly
        assembly {
            z := or(iszero(iszero(x)), iszero(iszero(y)))
        }
    }

    /// @dev Returns 1 if `b` is true, else 0. Input must be clean.
    function rawToUint(bool b) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            z := b
        }
    }

    /// @dev Returns 1 if `b` is true, else 0.
    function toUint(bool b) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            z := iszero(iszero(b))
        }
    }
}

Settings
{
  "remappings": [
    "openzeppelin/=lib/openzeppelin-contracts/contracts/",
    "openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "chiru-labs/ERC721A-Upgradeable/=lib/ERC721A-Upgradeable/contracts/",
    "solady/=lib/solady/src/",
    "closedsea/=lib/closedsea/src/",
    "preapprove/=lib/preapprove/src/",
    "multicaller/=lib/multicaller/src/",
    "@core/=contracts/core/",
    "@modules/=contracts/modules/",
    "forge-std/=lib/forge-std/src/",
    "ERC721A-Upgradeable/=lib/ERC721A-Upgradeable/contracts/",
    "ds-test/=lib/solady/lib/ds-test/src/",
    "erc4626-tests/=lib/closedsea/lib/openzeppelin-contracts/lib/erc4626-tests/",
    "erc721a-upgradeable/=lib/multicaller/lib/erc721a-upgradeable/contracts/",
    "erc721a/=lib/multicaller/lib/erc721a/contracts/",
    "murky/=lib/murky/src/",
    "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "operator-filter-registry/=lib/closedsea/lib/operator-filter-registry/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"name":"ArrayLengthsMismatch","type":"error"},{"inputs":[],"name":"ImplementationAddressCantBeZero","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"},{"indexed":true,"internalType":"address","name":"edition","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"bytes","name":"initData","type":"bytes"},{"indexed":false,"internalType":"address[]","name":"contracts","type":"address[]"},{"indexed":false,"internalType":"bytes[]","name":"data","type":"bytes[]"},{"indexed":false,"internalType":"bytes[]","name":"results","type":"bytes[]"}],"name":"Created","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"signer","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"nonces","type":"uint256[]"}],"name":"NoncesInvalidated","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"DOMAIN_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SOUND_CREATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"implementation","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"bytes","name":"initData","type":"bytes"},{"internalType":"address[]","name":"contracts","type":"address[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"internalType":"struct ISoundCreatorV2.SoundCreation","name":"c","type":"tuple"}],"name":"computeDigest","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"implementation","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"bytes","name":"initData","type":"bytes"},{"internalType":"address[]","name":"contracts","type":"address[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"internalType":"struct ISoundCreatorV2.SoundCreation","name":"c","type":"tuple"}],"name":"create","outputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"implementation","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"bytes","name":"initData","type":"bytes"},{"internalType":"address[]","name":"contracts","type":"address[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"internalType":"struct ISoundCreatorV2.SoundCreation","name":"creation","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"createWithSignature","outputs":[{"internalType":"address","name":"soundEdition","type":"address"},{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"implementation","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"bytes","name":"initData","type":"bytes"},{"internalType":"address[]","name":"contracts","type":"address[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"internalType":"struct ISoundCreatorV2.SoundCreation","name":"c","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"address","name":"minter","type":"address"},{"internalType":"bytes","name":"mintData","type":"bytes"},{"internalType":"address","name":"refundTo","type":"address"}],"name":"createWithSignatureAndMint","outputs":[{"internalType":"address","name":"edition","type":"address"},{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"domainSeparator","outputs":[{"internalType":"bytes32","name":"separator","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"nonces","type":"uint256[]"}],"name":"invalidateNonces","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"implementation","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"bytes","name":"initData","type":"bytes"},{"internalType":"address[]","name":"contracts","type":"address[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"internalType":"struct ISoundCreatorV2.SoundCreation","name":"c","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"},{"internalType":"bytes","name":"mintData","type":"bytes"},{"internalType":"address","name":"refundTo","type":"address"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"name_","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"uint256[]","name":"nonces","type":"uint256[]"}],"name":"noncesInvalidated","outputs":[{"internalType":"bool[]","name":"result","type":"bool[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"implementation","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"soundEditionAddress","outputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"version_","type":"string"}],"stateMutability":"pure","type":"function"},{"stateMutability":"payable","type":"receive"}]

61012060405234801561001157600080fd5b50306080524660a05260608061005e604080518082018252600c81526b29b7bab73221b932b0ba37b960a11b602080830191909152825180840190935260018352601960f91b9083015291565b815160209283012081519183019190912060c082905260e0819052604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8152938401929092529082015246606082015230608082015260a09020610100525050600160005560805160a05160c05160e05161010051611a3661011160003960008181610f420152610fa1015260006111a901526000611183015260006111e5015260006112080152611a366000f3fe6080604052600436106100ec5760003560e01c806354fd4d501161008a578063b9a257b211610059578063b9a257b2146102c1578063d38dfaf5146102e1578063e361d18f14610311578063f698da2514610331576100fb565b806354fd4d50146102115780637cf5b76314610226578063807c93101461025a57806384b0196e14610299576100fb565b806317447cf1116100c657806317447cf11461016f57806320606b701461019c5780632eb48a80146101de57806340a5468f146101fe576100fb565b806306fdde031461010357806308d1207f1461012e5780630ffc20c91461014f576100fb565b366100fb576100f9610346565b005b6100f9610346565b34801561010f57600080fd5b506101186103de565b6040516101259190611273565b60405180910390f35b61014161013c3660046112fc565b6103ee565b60405161012592919061140c565b34801561015b57600080fd5b5061014161016a366004611430565b610462565b34801561017b57600080fd5b5061018f61018a3660046114dc565b610490565b6040516101259190611521565b3480156101a857600080fd5b506101d07f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b604051908152602001610125565b3480156101ea57600080fd5b506100f96101f9366004611567565b610555565b6100f961020c3660046115a8565b6105ff565b34801561021d57600080fd5b50610118610623565b34801561023257600080fd5b506101d07f02851fd84c0125420e90b7716c63914a48e2932366cce89b4a7a0bcdf538d75981565b34801561026657600080fd5b5061027a61027536600461160c565b610633565b604080516001600160a01b039093168352901515602083015201610125565b3480156102a557600080fd5b506102ae6106c3565b6040516101259796959493929190611683565b3480156102cd57600080fd5b506101416102dc3660046116f3565b6106ea565b3480156102ed57600080fd5b506103016102fc366004611430565b61075a565b6040519015158152602001610125565b34801561031d57600080fd5b506101d061032c3660046116f3565b6107e3565b34801561033d57600080fd5b506101d06109e7565b3661034f573636f35b6000805b8036821061036157506103bd565b600180830192600319810190351860001a90816103ad57600019855260028301933560021984011860001a607f80821161039c578282013888395b169490940190930192506103539050565b8185538085019450505050610353565b50600080826000305af490503d6000803e806103d8573d6000fd5b503d6000f35b60606103e86109f6565b50919050565b600060606103fa610a34565b600061042661040c60208c018c611727565b61041c60408d0160208e01611727565b8c60400135610633565b9150508061043f576104398a8a8a610a92565b90935091505b61044b87878787610bc8565b506104566001600055565b97509795505050505050565b6000606061046e610a34565b610479858585610a92565b90925090506104886001600055565b935093915050565b6060816001600160401b038111156104aa576104aa611742565b6040519080825280602002602001820160405280156104d3578160200160208202803683370190505b506001600160a01b03851660009081526001602052604081209192505b80841461054c5761052285858381811061050c5761050c611758565b9050602002013583610c2990919063ffffffff16565b83828151811061053457610534611758565b911515602092830291909101909101526001016104f0565b50509392505050565b600061055f610c4b565b6001600160a01b03811660009081526001602052604081209192505b8084146105b5576105ad85858381811061059757610597611758565b9050602002013583610c8390919063ffffffff16565b60010161057b565b50816001600160a01b03167fc45e3a0dd412bcad8d62398d74d66b1c8449f38beb10da275e4da0c6d3a811a485856040516105f192919061176e565b60405180910390a250505050565b610607610a34565b61061384848484610bc8565b61061d6001600055565b50505050565b606061062d6109f6565b92915050565b602082905246600c5260008181526040812081906106ac90869030604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b8152606093841b60148201526f5af43d82803e903d91602b57fd5bf3ff60801b6028820152921b6038830152604c8201526037808220606c830152605591012090565b956001600160a01b0387163b151595509350505050565b600f60f81b60608060008080836106d86109f6565b97989097965046955030945091925090565b600060606106f6610a34565b6106fe610c4b565b6001600160a01b03166107176040850160208601611727565b6001600160a01b03161461073d576040516282b42960e81b815260040160405180910390fd5b61074683610cac565b90925090506107556001600055565b915091565b600061077f61076f6040860160208701611727565b610778866107e3565b8585610e95565b80156107db57506107d960c0850135600160006107a26040890160208a01611727565b6001600160a01b0316815260208082019290925260409081016000908120600885901c825290925290205460ff9091161c60011690565b155b949350505050565b60008036816107f560a08601866117a7565b9092509050806000816001600160401b0381111561081557610815611742565b60405190808252806020026020018201604052801561083e578160200160208202803683370190505b50905060005b8281146108aa5784848281811061085d5761085d611758565b905060200281019061086f91906117f0565b60405161087d929190611836565b604051809103902082828151811061089757610897611758565b6020908102919091010152600101610844565b50806040516020016108bc9190611846565b604051602081830303815290604052805190602001209450505050506109e07f02851fd84c0125420e90b7716c63914a48e2932366cce89b4a7a0bcdf538d75984600001602081019061090f9190611727565b61091f6040870160208801611727565b604087013561093160608901896117f0565b60405161093f929190611836565b60405190819003902061095560808a018a6117a7565b60405160200161096692919061187c565b60408051601f198184030181528282528051602091820120908301979097526001600160a01b0395861690820152939092166060840152608083015260a082015260c08082019290925260e08101849052908501356101008201526101200160405160208183030381529060405280519060200120610f3e565b9392505050565b60006109f1610f9f565b905090565b604080518082018252600c81526b29b7bab73221b932b0ba37b960a11b602080830191909152825180840190935260018352601960f91b9083015291565b600260005403610a8b5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b6002600055565b60006060610aa185858561075a565b610abe57604051638baa579f60e01b815260040160405180910390fd5b610ac785610cac565b9092509050610b2660c086013560016000610ae860408a0160208b01611727565b6001600160a01b0316815260208082019290925260409081016000908120600885901c825290925290208054600160ff9093169290921b9091179055565b604080516001808252818301909252600091602080830190803683370190505090508560c0013581600081518110610b6057610b60611758565b602002602001018181525050856020016020810190610b7f9190611727565b6001600160a01b03167fc45e3a0dd412bcad8d62398d74d66b1c8449f38beb10da275e4da0c6d3a811a482604051610bb791906118bc565b60405180910390a250935093915050565b6001600160a01b0384161561061d5760405182848237600080848334895af1610bf5573d6000803e3d6000fd5b506001600160a01b0381161561061d57471561061d576000196001600160a01b03821601610c205750335b61061d81610fd8565b600881901c6000908152602092909252604090912054600160ff9092161c1690565b6000336000526e2fd5aeb385d324b580fca7c83823a0803303610c7b5760206000806000845afa610c7b57600080fd5b505060005190565b600881901c600090815260209290925260409091208054600160ff9093169290921b9091179055565b6000606081610cbe6020850185611727565b6001600160a01b031603610ce557604051639841ec5160e01b815260040160405180910390fd5b610d23610cf56020850185611727565b610d1e610d086040870160208801611727565b60205246600c5260408087013560009081522090565b61100c565b9150366000610d3560608601866117f0565b915091506040518183823760008083836000895af1610d58573d6000803e3d6000fd5b50610d7b610d6960808701876117a7565b610d7660a08901896117a7565b6110ac565b92506001600160a01b03841663f2fde38b610d9c6040880160208901611727565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b158015610ddd57600080fd5b505af1158015610df1573d6000803e3d6000fd5b50610e06925050506040860160208701611727565b6001600160a01b03908116908516610e216020880188611727565b6001600160a01b03167fe94db3a31c09b7894f023c1f9114859672be916ffa8282215d7d43595bdcb3e7610e5860608a018a6117f0565b610e6560808c018c6117a7565b610e7260a08e018e6117a7565b8c604051610e8697969594939291906118f8565b60405180910390a45050915091565b6001600160a01b0390931692600084156107db5760405160418303610ef35784600052604084013560001a602052604084604037602060016080600060015afa805187183d1517610ef1575060006060526040525060016107db565b505b600060605280604052631626ba7e60e01b80825285600483015260248201604081528460448401528486606485013760208160648701858b5afa905190911416915050949350505050565b60007f0000000000000000000000000000000000000000000000000000000000000000610f696111e2565b15610f7957610f7661115a565b90505b67190100000000000060005280601a5282603a52604260182091506000603a5250919050565b7f0000000000000000000000000000000000000000000000000000000000000000610fc86111e2565b15610fd5576109f161115a565b90565b60005a60005a4785620186a0f161100957806000526073600b5360ff6020536016600b47f0611009575a60141c3d5a3e5b50565b6000604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81528360601b60148201526e5af43d82803e903d91602b57fd5bf360881b6028820152826037826000f59150506001600160a01b03811661062d5760405162461bcd60e51b815260206004820152601760248201527f455243313136373a2063726561746532206661696c65640000000000000000006044820152606401610a82565b60608382146110ce57604051631dc0052360e11b815260040160405180910390fd5b6040519050818152602081018260051b84018360051b8201855b82811461114b578035870180356020820184378782038a01356000808335866000855af161111a573d6000803e3d6000fd5b50508184526020840193503d82523d6000602084013e3d91909101603f0167ffffffffffffffe016906020016110e8565b50604052509095945050505050565b604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81527f000000000000000000000000000000000000000000000000000000000000000060208201527f00000000000000000000000000000000000000000000000000000000000000009181019190915246606082015230608082015260a0902090565b467f000000000000000000000000000000000000000000000000000000000000000014307f000000000000000000000000000000000000000000000000000000000000000014161590565b6000815180845260005b8181101561125357602081850181015186830182015201611237565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006109e0602083018461122d565b600060e082840312156103e857600080fd5b60008083601f8401126112aa57600080fd5b5081356001600160401b038111156112c157600080fd5b6020830191508360208285010111156112d957600080fd5b9250929050565b80356001600160a01b03811681146112f757600080fd5b919050565b600080600080600080600060a0888a03121561131757600080fd5b87356001600160401b038082111561132e57600080fd5b61133a8b838c01611286565b985060208a013591508082111561135057600080fd5b61135c8b838c01611298565b909850965086915061137060408b016112e0565b955060608a013591508082111561138657600080fd5b506113938a828b01611298565b90945092506113a69050608089016112e0565b905092959891949750929550565b600082825180855260208086019550808260051b84010181860160005b848110156113ff57601f198684030189526113ed83835161122d565b988401989250908301906001016113d1565b5090979650505050505050565b6001600160a01b03831681526040602082018190526000906107db908301846113b4565b60008060006040848603121561144557600080fd5b83356001600160401b038082111561145c57600080fd5b61146887838801611286565b9450602086013591508082111561147e57600080fd5b5061148b86828701611298565b9497909650939450505050565b60008083601f8401126114aa57600080fd5b5081356001600160401b038111156114c157600080fd5b6020830191508360208260051b85010111156112d957600080fd5b6000806000604084860312156114f157600080fd5b6114fa846112e0565b925060208401356001600160401b0381111561151557600080fd5b61148b86828701611498565b6020808252825182820181905260009190848201906040850190845b8181101561155b57835115158352928401929184019160010161153d565b50909695505050505050565b6000806020838503121561157a57600080fd5b82356001600160401b0381111561159057600080fd5b61159c85828601611498565b90969095509350505050565b600080600080606085870312156115be57600080fd5b6115c7856112e0565b935060208501356001600160401b038111156115e257600080fd5b6115ee87828801611298565b90945092506116019050604086016112e0565b905092959194509250565b60008060006060848603121561162157600080fd5b61162a846112e0565b9250611638602085016112e0565b9150604084013590509250925092565b600081518084526020808501945080840160005b838110156116785781518752958201959082019060010161165c565b509495945050505050565b60ff60f81b8816815260e0602082015260006116a260e083018961122d565b82810360408401526116b4818961122d565b606084018890526001600160a01b038716608085015260a0840186905283810360c085015290506116e58185611648565b9a9950505050505050505050565b60006020828403121561170557600080fd5b81356001600160401b0381111561171b57600080fd5b6107db84828501611286565b60006020828403121561173957600080fd5b6109e0826112e0565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6020808252810182905260006001600160fb1b0383111561178e57600080fd5b8260051b80856040850137919091016040019392505050565b6000808335601e198436030181126117be57600080fd5b8301803591506001600160401b038211156117d857600080fd5b6020019150600581901b36038213156112d957600080fd5b6000808335601e1984360301811261180757600080fd5b8301803591506001600160401b0382111561182157600080fd5b6020019150368190038213156112d957600080fd5b8183823760009101908152919050565b815160009082906020808601845b8381101561187057815185529382019390820190600101611854565b50929695505050505050565b60008184825b858110156118b1576001600160a01b0361189b836112e0565b1683526020928301929190910190600101611882565b509095945050505050565b6020815260006109e06020830184611648565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60808152600061190c60808301898b6118cf565b8281036020848101919091528782528891810160005b8981101561194e576001600160a01b0361193b856112e0565b1682529282019290820190600101611922565b5084810360408601528681528181019250600587901b810182018860005b898110156119db57838303601f190186528135368c9003601e1901811261199257600080fd5b8b0185810190356001600160401b038111156119ad57600080fd5b8036038213156119bc57600080fd5b6119c78582846118cf565b97870197945050509084019060010161196c565b505085810360608701526119ef81886113b4565b9d9c5050505050505050505050505056fea2646970667358221220d594684cddf3261cd3a8d49bc981d492299a30b7d35d1bd5669ccd0bcc4c29dd64736f6c63430008130033

Deployed Bytecode

0x6080604052600436106100ec5760003560e01c806354fd4d501161008a578063b9a257b211610059578063b9a257b2146102c1578063d38dfaf5146102e1578063e361d18f14610311578063f698da2514610331576100fb565b806354fd4d50146102115780637cf5b76314610226578063807c93101461025a57806384b0196e14610299576100fb565b806317447cf1116100c657806317447cf11461016f57806320606b701461019c5780632eb48a80146101de57806340a5468f146101fe576100fb565b806306fdde031461010357806308d1207f1461012e5780630ffc20c91461014f576100fb565b366100fb576100f9610346565b005b6100f9610346565b34801561010f57600080fd5b506101186103de565b6040516101259190611273565b60405180910390f35b61014161013c3660046112fc565b6103ee565b60405161012592919061140c565b34801561015b57600080fd5b5061014161016a366004611430565b610462565b34801561017b57600080fd5b5061018f61018a3660046114dc565b610490565b6040516101259190611521565b3480156101a857600080fd5b506101d07f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b604051908152602001610125565b3480156101ea57600080fd5b506100f96101f9366004611567565b610555565b6100f961020c3660046115a8565b6105ff565b34801561021d57600080fd5b50610118610623565b34801561023257600080fd5b506101d07f02851fd84c0125420e90b7716c63914a48e2932366cce89b4a7a0bcdf538d75981565b34801561026657600080fd5b5061027a61027536600461160c565b610633565b604080516001600160a01b039093168352901515602083015201610125565b3480156102a557600080fd5b506102ae6106c3565b6040516101259796959493929190611683565b3480156102cd57600080fd5b506101416102dc3660046116f3565b6106ea565b3480156102ed57600080fd5b506103016102fc366004611430565b61075a565b6040519015158152602001610125565b34801561031d57600080fd5b506101d061032c3660046116f3565b6107e3565b34801561033d57600080fd5b506101d06109e7565b3661034f573636f35b6000805b8036821061036157506103bd565b600180830192600319810190351860001a90816103ad57600019855260028301933560021984011860001a607f80821161039c578282013888395b169490940190930192506103539050565b8185538085019450505050610353565b50600080826000305af490503d6000803e806103d8573d6000fd5b503d6000f35b60606103e86109f6565b50919050565b600060606103fa610a34565b600061042661040c60208c018c611727565b61041c60408d0160208e01611727565b8c60400135610633565b9150508061043f576104398a8a8a610a92565b90935091505b61044b87878787610bc8565b506104566001600055565b97509795505050505050565b6000606061046e610a34565b610479858585610a92565b90925090506104886001600055565b935093915050565b6060816001600160401b038111156104aa576104aa611742565b6040519080825280602002602001820160405280156104d3578160200160208202803683370190505b506001600160a01b03851660009081526001602052604081209192505b80841461054c5761052285858381811061050c5761050c611758565b9050602002013583610c2990919063ffffffff16565b83828151811061053457610534611758565b911515602092830291909101909101526001016104f0565b50509392505050565b600061055f610c4b565b6001600160a01b03811660009081526001602052604081209192505b8084146105b5576105ad85858381811061059757610597611758565b9050602002013583610c8390919063ffffffff16565b60010161057b565b50816001600160a01b03167fc45e3a0dd412bcad8d62398d74d66b1c8449f38beb10da275e4da0c6d3a811a485856040516105f192919061176e565b60405180910390a250505050565b610607610a34565b61061384848484610bc8565b61061d6001600055565b50505050565b606061062d6109f6565b92915050565b602082905246600c5260008181526040812081906106ac90869030604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b8152606093841b60148201526f5af43d82803e903d91602b57fd5bf3ff60801b6028820152921b6038830152604c8201526037808220606c830152605591012090565b956001600160a01b0387163b151595509350505050565b600f60f81b60608060008080836106d86109f6565b97989097965046955030945091925090565b600060606106f6610a34565b6106fe610c4b565b6001600160a01b03166107176040850160208601611727565b6001600160a01b03161461073d576040516282b42960e81b815260040160405180910390fd5b61074683610cac565b90925090506107556001600055565b915091565b600061077f61076f6040860160208701611727565b610778866107e3565b8585610e95565b80156107db57506107d960c0850135600160006107a26040890160208a01611727565b6001600160a01b0316815260208082019290925260409081016000908120600885901c825290925290205460ff9091161c60011690565b155b949350505050565b60008036816107f560a08601866117a7565b9092509050806000816001600160401b0381111561081557610815611742565b60405190808252806020026020018201604052801561083e578160200160208202803683370190505b50905060005b8281146108aa5784848281811061085d5761085d611758565b905060200281019061086f91906117f0565b60405161087d929190611836565b604051809103902082828151811061089757610897611758565b6020908102919091010152600101610844565b50806040516020016108bc9190611846565b604051602081830303815290604052805190602001209450505050506109e07f02851fd84c0125420e90b7716c63914a48e2932366cce89b4a7a0bcdf538d75984600001602081019061090f9190611727565b61091f6040870160208801611727565b604087013561093160608901896117f0565b60405161093f929190611836565b60405190819003902061095560808a018a6117a7565b60405160200161096692919061187c565b60408051601f198184030181528282528051602091820120908301979097526001600160a01b0395861690820152939092166060840152608083015260a082015260c08082019290925260e08101849052908501356101008201526101200160405160208183030381529060405280519060200120610f3e565b9392505050565b60006109f1610f9f565b905090565b604080518082018252600c81526b29b7bab73221b932b0ba37b960a11b602080830191909152825180840190935260018352601960f91b9083015291565b600260005403610a8b5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b6002600055565b60006060610aa185858561075a565b610abe57604051638baa579f60e01b815260040160405180910390fd5b610ac785610cac565b9092509050610b2660c086013560016000610ae860408a0160208b01611727565b6001600160a01b0316815260208082019290925260409081016000908120600885901c825290925290208054600160ff9093169290921b9091179055565b604080516001808252818301909252600091602080830190803683370190505090508560c0013581600081518110610b6057610b60611758565b602002602001018181525050856020016020810190610b7f9190611727565b6001600160a01b03167fc45e3a0dd412bcad8d62398d74d66b1c8449f38beb10da275e4da0c6d3a811a482604051610bb791906118bc565b60405180910390a250935093915050565b6001600160a01b0384161561061d5760405182848237600080848334895af1610bf5573d6000803e3d6000fd5b506001600160a01b0381161561061d57471561061d576000196001600160a01b03821601610c205750335b61061d81610fd8565b600881901c6000908152602092909252604090912054600160ff9092161c1690565b6000336000526e2fd5aeb385d324b580fca7c83823a0803303610c7b5760206000806000845afa610c7b57600080fd5b505060005190565b600881901c600090815260209290925260409091208054600160ff9093169290921b9091179055565b6000606081610cbe6020850185611727565b6001600160a01b031603610ce557604051639841ec5160e01b815260040160405180910390fd5b610d23610cf56020850185611727565b610d1e610d086040870160208801611727565b60205246600c5260408087013560009081522090565b61100c565b9150366000610d3560608601866117f0565b915091506040518183823760008083836000895af1610d58573d6000803e3d6000fd5b50610d7b610d6960808701876117a7565b610d7660a08901896117a7565b6110ac565b92506001600160a01b03841663f2fde38b610d9c6040880160208901611727565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b158015610ddd57600080fd5b505af1158015610df1573d6000803e3d6000fd5b50610e06925050506040860160208701611727565b6001600160a01b03908116908516610e216020880188611727565b6001600160a01b03167fe94db3a31c09b7894f023c1f9114859672be916ffa8282215d7d43595bdcb3e7610e5860608a018a6117f0565b610e6560808c018c6117a7565b610e7260a08e018e6117a7565b8c604051610e8697969594939291906118f8565b60405180910390a45050915091565b6001600160a01b0390931692600084156107db5760405160418303610ef35784600052604084013560001a602052604084604037602060016080600060015afa805187183d1517610ef1575060006060526040525060016107db565b505b600060605280604052631626ba7e60e01b80825285600483015260248201604081528460448401528486606485013760208160648701858b5afa905190911416915050949350505050565b60007ff925c052d7deab5d3e4719e7b25c61cc3fd165a61b045233d6fc4cbce22d85cc610f696111e2565b15610f7957610f7661115a565b90505b67190100000000000060005280601a5282603a52604260182091506000603a5250919050565b7ff925c052d7deab5d3e4719e7b25c61cc3fd165a61b045233d6fc4cbce22d85cc610fc86111e2565b15610fd5576109f161115a565b90565b60005a60005a4785620186a0f161100957806000526073600b5360ff6020536016600b47f0611009575a60141c3d5a3e5b50565b6000604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81528360601b60148201526e5af43d82803e903d91602b57fd5bf360881b6028820152826037826000f59150506001600160a01b03811661062d5760405162461bcd60e51b815260206004820152601760248201527f455243313136373a2063726561746532206661696c65640000000000000000006044820152606401610a82565b60608382146110ce57604051631dc0052360e11b815260040160405180910390fd5b6040519050818152602081018260051b84018360051b8201855b82811461114b578035870180356020820184378782038a01356000808335866000855af161111a573d6000803e3d6000fd5b50508184526020840193503d82523d6000602084013e3d91909101603f0167ffffffffffffffe016906020016110e8565b50604052509095945050505050565b604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81527f055447914107b5dcd4afdd0a0ec9b0df7575160486e48acf346f43310273a5fa60208201527fad7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a59181019190915246606082015230608082015260a0902090565b467f000000000000000000000000000000000000000000000000000000000000000114307f0000000000000000000000000000000000aec84f5bfc2af15eafb943bf4e352214161590565b6000815180845260005b8181101561125357602081850181015186830182015201611237565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006109e0602083018461122d565b600060e082840312156103e857600080fd5b60008083601f8401126112aa57600080fd5b5081356001600160401b038111156112c157600080fd5b6020830191508360208285010111156112d957600080fd5b9250929050565b80356001600160a01b03811681146112f757600080fd5b919050565b600080600080600080600060a0888a03121561131757600080fd5b87356001600160401b038082111561132e57600080fd5b61133a8b838c01611286565b985060208a013591508082111561135057600080fd5b61135c8b838c01611298565b909850965086915061137060408b016112e0565b955060608a013591508082111561138657600080fd5b506113938a828b01611298565b90945092506113a69050608089016112e0565b905092959891949750929550565b600082825180855260208086019550808260051b84010181860160005b848110156113ff57601f198684030189526113ed83835161122d565b988401989250908301906001016113d1565b5090979650505050505050565b6001600160a01b03831681526040602082018190526000906107db908301846113b4565b60008060006040848603121561144557600080fd5b83356001600160401b038082111561145c57600080fd5b61146887838801611286565b9450602086013591508082111561147e57600080fd5b5061148b86828701611298565b9497909650939450505050565b60008083601f8401126114aa57600080fd5b5081356001600160401b038111156114c157600080fd5b6020830191508360208260051b85010111156112d957600080fd5b6000806000604084860312156114f157600080fd5b6114fa846112e0565b925060208401356001600160401b0381111561151557600080fd5b61148b86828701611498565b6020808252825182820181905260009190848201906040850190845b8181101561155b57835115158352928401929184019160010161153d565b50909695505050505050565b6000806020838503121561157a57600080fd5b82356001600160401b0381111561159057600080fd5b61159c85828601611498565b90969095509350505050565b600080600080606085870312156115be57600080fd5b6115c7856112e0565b935060208501356001600160401b038111156115e257600080fd5b6115ee87828801611298565b90945092506116019050604086016112e0565b905092959194509250565b60008060006060848603121561162157600080fd5b61162a846112e0565b9250611638602085016112e0565b9150604084013590509250925092565b600081518084526020808501945080840160005b838110156116785781518752958201959082019060010161165c565b509495945050505050565b60ff60f81b8816815260e0602082015260006116a260e083018961122d565b82810360408401526116b4818961122d565b606084018890526001600160a01b038716608085015260a0840186905283810360c085015290506116e58185611648565b9a9950505050505050505050565b60006020828403121561170557600080fd5b81356001600160401b0381111561171b57600080fd5b6107db84828501611286565b60006020828403121561173957600080fd5b6109e0826112e0565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6020808252810182905260006001600160fb1b0383111561178e57600080fd5b8260051b80856040850137919091016040019392505050565b6000808335601e198436030181126117be57600080fd5b8301803591506001600160401b038211156117d857600080fd5b6020019150600581901b36038213156112d957600080fd5b6000808335601e1984360301811261180757600080fd5b8301803591506001600160401b0382111561182157600080fd5b6020019150368190038213156112d957600080fd5b8183823760009101908152919050565b815160009082906020808601845b8381101561187057815185529382019390820190600101611854565b50929695505050505050565b60008184825b858110156118b1576001600160a01b0361189b836112e0565b1683526020928301929190910190600101611882565b509095945050505050565b6020815260006109e06020830184611648565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60808152600061190c60808301898b6118cf565b8281036020848101919091528782528891810160005b8981101561194e576001600160a01b0361193b856112e0565b1682529282019290820190600101611922565b5084810360408601528681528181019250600587901b810182018860005b898110156119db57838303601f190186528135368c9003601e1901811261199257600080fd5b8b0185810190356001600160401b038111156119ad57600080fd5b8036038213156119bc57600080fd5b6119c78582846118cf565b97870197945050509084019060010161196c565b505085810360608701526119ef81886113b4565b9d9c5050505050505050505050505056fea2646970667358221220d594684cddf3261cd3a8d49bc981d492299a30b7d35d1bd5669ccd0bcc4c29dd64736f6c63430008130033

Deployed Bytecode Sourcemap

881:17100:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4448:19;:17;:19::i;:::-;881:17100;;4318:19;:17;:19::i;7174:112::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3211:568;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;2637:277::-;;;;;;;;;;-1:-1:-1;2637:277:0;;;;;:::i;:::-;;:::i;6706:384::-;;;;;;;;;;-1:-1:-1;6706:384:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1721:58::-;;;;;;;;;;-1:-1:-1;1721:58:0;1250:66:6;1721:58:0;;;;;5817:25:12;;;5805:2;5790:18;1721:58:0;5671:177:12;3836:377:0;;;;;;;;;;-1:-1:-1;3836:377:0;;;;;:::i;:::-;;:::i;2971:183::-;;;;;;:::i;:::-;;:::i;7343:121::-;;;;;;;;;;;;;:::i;1250:394::-;;;;;;;;;;;;1335:309;1250:394;;4724:315;;;;;;;;;;-1:-1:-1;4724:315:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;7376:32:12;;;7358:51;;7452:14;;7445:22;7440:2;7425:18;;7418:50;7331:18;4724:315:0;7190:284:12;6926:596:6;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;2347:233:0:-;;;;;;;;;;-1:-1:-1;2347:233:0;;;;;:::i;:::-;;:::i;5096:440::-;;;;;;;;;;-1:-1:-1;5096:440:0;;;;;:::i;:::-;;:::i;:::-;;;9381:14:12;;9374:22;9356:41;;9344:2;9329:18;5096:440:0;9216:187:12;5593:1056:0;;;;;;;;;;-1:-1:-1;5593:1056:0;;;;;:::i;:::-;;:::i;7521:116::-;;;;;;;;;;;;;:::i;11272:1120:9:-;11346:14;11336:68;;11346:14;;11364:38;11336:68;11426:1;;11503:628;11522:21;11346:14;11525:1;11522:21;;;-1:-1:-1;;;11522:21:9;11643:1;11636:9;;;;-1:-1:-1;;11586:9:9;;11597:15;;11582:31;11426:1;11574:40;;;11662:394;;-1:-1:-1;;11856:17:9;;11718:9;11772;;;11729:15;-1:-1:-1;;11718:9:9;;11714:31;11426:1;11706:40;11910:4;11904:11;;;11894:61;;11643:1;11947;11943:9;11931:10;11928:1;11919:34;11894:61;11992:12;11981:28;;;;;;;;-1:-1:-1;11503:628:9;;-1:-1:-1;11503:628:9;11662:394;12084:1;12081;12073:13;11643:1;12112;12108:9;12103:14;;;;;11503:628;;;11507:14;11426:1;;12196;11426;12179:9;12172:5;12159:51;12144:66;;12250:16;11426:1;;12223:44;12290:7;12280:53;;12314:16;11426:1;12301:30;12280:53;;12359:16;11426:1;12346:30;7174:112:0;7213:19;7256:23;:21;:23::i;:::-;-1:-1:-1;7244:35:0;7174:112;-1:-1:-1;7174:112:0:o;3211:568::-;3443:15;3460:22;2246:21:4;:19;:21::i;:::-;3582:11:0::1;3597:54;3617:16;;::::0;::::1;:1:::0;:16:::1;:::i;:::-;3635:7;::::0;;;::::1;::::0;::::1;;:::i;:::-;3644:1;:6;;;3597:19;:54::i;:::-;3579:72;;;3666:6;3661:68;;3695:34;3716:1;3719:9;;3695:20;:34::i;:::-;3674:55:::0;;-1:-1:-1;3674:55:0;-1:-1:-1;3661:68:0::1;3739:33;3745:6;3753:8;;3763;3739:5;:33::i;:::-;3484:295;2288:20:4::0;1701:1;2790:7;:22;2610:209;2288:20;3211:568:0;;;;;;;;;;:::o;2637:277::-;2780:20;2802:22;2246:21:4;:19;:21::i;:::-;2866:41:0::1;2887:8;2897:9;;2866:20;:41::i;:::-;2840:67:::0;;-1:-1:-1;2840:67:0;-1:-1:-1;2288:20:4;1701:1;2790:7;:22;2610:209;2288:20;2637:277:0;;;;;;:::o;6706:384::-;6799:20;6875:6;-1:-1:-1;;;;;6864:25:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6864:25:0;-1:-1:-1;;;;;;6932:26:0;;6903;6932;;;:18;:26;;;;;6855:34;;-1:-1:-1;6972:102:0;6988:18;;;6972:102;;7043:16;7049:6;;7056:1;7049:9;;;;;;;:::i;:::-;;;;;;;7043:1;:5;;:16;;;;:::i;:::-;7031:6;7038:1;7031:9;;;;;;;;:::i;:::-;:28;;;:9;;;;;;;;;;;:28;7008:3;;6972:102;;;;6831:253;6706:384;;;;;:::o;3836:377::-;3932:14;3949:23;:21;:23::i;:::-;-1:-1:-1;;;;;4015:26:0;;3986;4015;;;:18;:26;;;;;3932:40;;-1:-1:-1;4055:90:0;4071:18;;;4055:90;;4114:16;4120:6;;4127:1;4120:9;;;;;;;:::i;:::-;;;;;;;4114:1;:5;;:16;;;;:::i;:::-;4091:3;;4055:90;;;;4181:6;-1:-1:-1;;;;;4163:33:0;;4189:6;;4163:33;;;;;;;:::i;:::-;;;;;;;;3908:299;;3836:377;;:::o;2971:183::-;2246:21:4;:19;:21::i;:::-;3114:33:0::1;3120:6;3128:8;;3138;3114:5;:33::i;:::-;2288:20:4::0;1701:1;2790:7;:22;2610:209;2288:20;2971:183:0;;;;:::o;7343:121::-;7385:22;7434:23;:21;:23::i;:::-;7419:38;7343:121;-1:-1:-1;;7343:121:0:o;4724:315::-;12746:4;12739:19;;;12784:9;12778:4;12771:23;4857:12;12807:18;;;12864:4;12848:21;;4857:12;;4901:91;;4936:14;;4986:4;2867::3;2861:11;-1:-1:-1;;;2885:79:3;;3004:4;3000:25;;;2993:4;2984:14;;2977:49;-1:-1:-1;;;3055:4:3;3046:14;;3039:90;3165:19;;3158:4;3149:14;;3142:43;3214:4;3205:14;;3198:28;3277:4;3262:20;;;3255:4;3246:14;;3239:44;3335:4;3319:14;;3309:31;;2609:747;4901:91:0;4894:98;-1:-1:-1;;;;;5011:16:0;;;:21;;;-1:-1:-1;4724:315:0;-1:-1:-1;;;;4724:315:0:o;6926:596:6:-;-1:-1:-1;;;7051:18:6;;7024:13;;;7051:18;7322:23;:21;:23::i;:::-;6926:596;;7304:41;;;-1:-1:-1;7365:13:6;;-1:-1:-1;7416:4:6;;-1:-1:-1;6926:596:6;;-1:-1:-1;6926:596:6;:::o;2347:233:0:-;2420:15;2437:22;2246:21:4;:19;:21::i;:::-;2486:23:0::1;:21;:23::i;:::-;-1:-1:-1::0;;;;;2475:34:0::1;:7;::::0;;;::::1;::::0;::::1;;:::i;:::-;-1:-1:-1::0;;;;;2475:34:0::1;;2471:61;;2518:14;;-1:-1:-1::0;;;2518:14:0::1;;;;;;;;;;;2471:61;2563:10;2571:1;2563:7;:10::i;:::-;2542:31:::0;;-1:-1:-1;2542:31:0;-1:-1:-1;2288:20:4;1701:1;2790:7;:22;2610:209;2288:20;2347:233:0;;;:::o;5096:440::-;5195:4;5319:85;5367:7;;;;;;;;:::i;:::-;5376:16;5390:1;5376:13;:16::i;:::-;5394:9;;5319:47;:85::i;:::-;:210;;;;-1:-1:-1;5489:40:0;5521:7;;;;5489:18;:27;5508:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;5489:27:0;;;;;;;;;;;;;;;-1:-1:-1;5489:27:0;;;2024:1:8;2015:10;;;2004:22;;;;;;;;2039:4;2031:12;;;2004:40;2048:1;2003:46;;1672:479;5489:40:0;5488:41;5319:210;5211:318;5096:440;-1:-1:-1;;;;5096:440:0:o;5593:1056::-;5663:7;;5739:22;5663:7;5764:6;;;;:1;:6;:::i;:::-;5739:31;;-1:-1:-1;5739:31:0;-1:-1:-1;5739:31:0;5784:9;5739:31;-1:-1:-1;;;;;5853:16:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5853:16:0;;5822:47;;5888:9;5883:102;5908:1;5903;:6;5883:102;;5961:5;;5967:1;5961:8;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;5951:19;;;;;;;:::i;:::-;;;;;;;;5934:11;5946:1;5934:14;;;;;;;;:::i;:::-;;;;;;;;;;:36;5911:3;;5883:102;;;;6043:11;6026:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;6016:40;;;;;;5998:58;;5715:352;;;;6095:547;1335:309;6243:1;:16;;;;;;;;;;:::i;:::-;6296:7;;;;;;;;:::i;:::-;6340:6;;;;6393:10;;;;6340:1;6393:10;:::i;:::-;6383:21;;;;;;;:::i;:::-;;;;;;;;;6466:11;;;;:1;:11;:::i;:::-;6449:29;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;6449:29:0;;;;;;;;;6439:40;;6449:29;6439:40;;;;6158:452;;;13671:25:12;;;;-1:-1:-1;;;;;13770:15:12;;;13750:18;;;13743:43;13822:15;;;;13802:18;;;13795:43;13854:18;;;13847:34;13897:19;;;13890:35;6570:7:0;13941:19:12;;;13934:35;;;;13985:19;;;13978:35;;;6570:7:0;;;;14029:19:12;;;14022:35;13643:19;;6158:452:0;;;;;;;;;;;;6127:501;;;;;;6095:14;:547::i;:::-;6076:566;5593:1056;-1:-1:-1;;;5593:1056:0:o;7521:116::-;7571:17;7612:18;:16;:18::i;:::-;7600:30;;7521:116;:::o;7970:225::-;8142:22;;;;;;;;;;;-1:-1:-1;;;8142:22:0;;;;;;;;8174:14;;;;;;;;;;;-1:-1:-1;;;8174:14:0;;;;8142:22;7970:225::o;2321:283:4:-;1744:1;2449:7;;:19;2441:63;;;;-1:-1:-1;;;2441:63:4;;14270:2:12;2441:63:4;;;14252:21:12;14309:2;14289:18;;;14282:30;14348:33;14328:18;;;14321:61;14399:18;;2441:63:4;;;;;;;;;1744:1;2579:7;:18;2321:283::o;15196:514:0:-;15312:15;15329:22;15372:30;15389:1;15392:9;;15372:16;:30::i;:::-;15367:62;;15411:18;;-1:-1:-1;;;15411:18:0;;;;;;;;;;;15367:62;15460:10;15468:1;15460:7;:10::i;:::-;15439:31;;-1:-1:-1;15439:31:0;-1:-1:-1;15533:40:0;15565:7;;;;15533:18;:27;15552:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;15533:27:0;;;;;;;;;;;;;;;-1:-1:-1;15533:27:0;;;2308:1:8;2299:10;;;2288:22;;;;;;;:47;;2315:1;2329:4;2321:12;;;2315:19;;;;2288:47;;;;;2218:124;15533:40:0;15609:16;;;15623:1;15609:16;;;;;;;;;15583:23;;15609:16;;;;;;;;;;;-1:-1:-1;15609:16:0;15583:42;;15647:1;:7;;;15635:6;15642:1;15635:9;;;;;;;;:::i;:::-;;;;;;:19;;;;;15687:1;:7;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;15669:34:0;;15696:6;15669:34;;;;;;:::i;:::-;;;;;;;;15357:353;15196:514;;;;;;:::o;16417:1562::-;-1:-1:-1;;;;;16544:20:0;;16540:33;16566:7;16540:33;16665:4;16659:11;16773:15;16756;16753:1;16740:49;17296:4;17233;17171:15;17110:1;17039:11;16985:6;16940:5;16914:441;16887:666;;17475:16;17469:4;17463;17448:44;17522:16;17516:4;17509:30;16887:666;-1:-1:-1;;;;;;17576:22:0;;;17572:401;;17786:21;:26;17782:181;;-1:-1:-1;;;;;;;17836:22:0;;;17832:49;;-1:-1:-1;17871:10:0;17832:49;17899;17939:8;17899:39;:49::i;1672:479:8:-;2024:1;2015:10;;;1746;2004:22;;;;;;;;;;;;;2048:1;2039:4;2031:12;;;2004:40;2003:46;;1672:479::o;1961:485:2:-;2002:14;2107:8;2101:4;2094:22;2147:23;2199:10;2189:8;2186:24;2183:213;;2287:4;2281;2275;2269;2257:10;2250:5;2239:53;2229:153;;2329:4;2323;2316:18;2229:153;-1:-1:-1;;2425:4:2;2419:11;;1961:485::o;2218:124:8:-;2308:1;2299:10;;;2288;:22;;;;;;;;;;;;:47;;2315:1;2329:4;2321:12;;;2315:19;;;;2288:47;;;;;2218:124::o;13245:1545:0:-;13306:15;13323:22;13306:15;13361:16;;;;:1;:16;:::i;:::-;-1:-1:-1;;;;;13361:30:0;;13357:76;;13400:33;;-1:-1:-1;;;13400:33:0;;;;;;;;;;;13357:76;13501:73;13527:16;;;;:1;:16;:::i;:::-;13545:28;13557:7;;;;;;;;:::i;:::-;12746:4;12739:19;12784:9;12778:4;12771:23;13566:6;;;;;12690:14;12807:18;;;12848:21;;12617:268;13545:28;13501:25;:73::i;:::-;13483:92;-1:-1:-1;13586:23:0;;13612:10;;;;:1;:10;:::i;:::-;13586:36;;;;13744:4;13738:11;13850:15;13833;13830:1;13817:49;14313:4;14257;14200:15;14158:1;14100;14044:7;13999:5;13973:391;13946:617;;14485:16;14479:4;14473;14458:44;14532:16;14526:4;14519:30;13946:617;-1:-1:-1;14593:35:0;14608:11;;;;:1;:11;:::i;:::-;14621:6;;;;:1;:6;:::i;:::-;14593:14;:35::i;:::-;14583:45;-1:-1:-1;;;;;;14639:34:0;;;14674:7;;;;;;;;:::i;:::-;14639:43;;-1:-1:-1;;;;;;14639:43:0;;;;;;;-1:-1:-1;;;;;14858:32:12;;;14639:43:0;;;14840:51:12;14813:18;;14639:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14733:7:0;;-1:-1:-1;;;14733:7:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;14698:85:0;;;;;;14706:16;;;;:1;:16;:::i;:::-;-1:-1:-1;;;;;14698:85:0;;14742:10;;;;:1;:10;:::i;:::-;14754:11;;;;:1;:11;:::i;:::-;14767:6;;;;:1;:6;:::i;:::-;14775:7;14698:85;;;;;;;;;;;;:::i;:::-;;;;;;;;13347:1443;;13245:1545;;;:::o;4820:3036:11:-;-1:-1:-1;;;;;5145:24:11;;;;4960:12;5172:6;5129:2711;;;5215:4;5209:11;5261:2;5243:16;5240:24;5237:1102;;5300:4;5294;5287:18;5382:4;5364:16;5360:27;5347:41;5344:1;5339:50;5333:4;5326:64;5456:4;5438:16;5432:4;5419:42;5863:4;5809;5757;5704;5646:1;5568:5;5528:384;6083:1;6077:8;6069:6;6065:21;6046:16;6039:24;6036:51;6026:295;;-1:-1:-1;6165:1:11;6159:4;6152:15;6225:4;6218:15;-1:-1:-1;6126:1:11;6294:5;;6026:295;;5237:1102;6369:1;6363:4;6356:15;6427:1;6421:4;6414:15;6501:10;6496:3;6492:20;6539:1;6536;6529:12;6638:4;6631;6628:1;6624:12;6617:26;6676:4;6673:1;6669:12;6708:4;6705:1;6698:15;6801:16;6794:4;6791:1;6787:12;6780:38;6926:16;6908;6901:4;6898:1;6894:12;6881:62;7726:4;7674:1;7610:4;7592:16;7588:27;7528:1;7471:6;7422:5;7386:400;7140:8;;7137:15;;;7018:786;;-1:-1:-1;;4820:3036:11;;;;;;:::o;5739:840:6:-;5814:14;5997:22;6037:35;:33;:35::i;:::-;6033:76;;;6086:23;:21;:23::i;:::-;6074:35;;6033:76;6243:18;6237:4;6230:32;6309:9;6303:4;6296:23;6376:10;6370:4;6363:24;6452:4;6446;6436:21;6426:31;;6561:1;6555:4;6548:15;6181:392;5739:840;;;:::o;4781:347::-;4999:22;5039:35;:33;:35::i;:::-;5035:76;;;5088:23;:21;:23::i;5035:76::-;4781:347;:::o;6455:614:10:-;6661:4;6654:5;6648:4;6641:5;6626:13;6622:2;6600:20;6595:71;6585:468;;6699:2;6693:4;6686:16;6772:4;6766;6758:19;6828:4;6822;6814:19;6914:4;6908;6893:13;6886:33;6876:163;;6991:5;6987:2;6983:14;6965:16;6958:5;6943:55;6876:163;6455:614;:::o;1906:593:3:-;1990:16;2101:4;2095:11;-1:-1:-1;;;2126:3:3;2119:79;2244:14;2238:4;2234:25;2227:4;2222:3;2218:14;2211:49;-1:-1:-1;;;2289:4:3;2284:3;2280:14;2273:90;2410:4;2404;2399:3;2396:1;2388:27;2376:39;-1:-1:-1;;;;;;;2442:22:3;;2434:58;;;;-1:-1:-1;;;2434:58:3;;17456:2:12;2434:58:3;;;17438:21:12;17495:2;17475:18;;;17468:30;17534:25;17514:18;;;17507:53;17577:18;;2434:58:3;17254:347:12;8478:3795:0;8589:22;8631:31;;;8627:66;;8671:22;;-1:-1:-1;;;8671:22:0;;;;;;;;;;;8627:66;8929:4;8923:11;8912:22;;9029:11;9020:7;9013:28;9159:4;9150:7;9146:18;9371:11;9368:1;9364:19;9351:11;9347:37;9575:11;9572:1;9568:19;9552:14;9548:40;9708:11;9693:2450;9735:14;9732:1;9729:21;9693:2450;;9886:1;9873:15;9860:11;9856:33;10170:1;10157:15;10075:4;10072:1;10068:12;10009:1;9975:248;10569:11;10566:1;10562:19;10544:16;10540:42;10527:56;11093:4;11033;10972:1;10959:15;10886:1;10824;10778;10729:5;10699:449;10668:699;;11281:16;11275:4;11269;11254:44;11332:16;11326:4;11319:30;10668:699;;;11472:1;11456:14;11449:25;11529:4;11513:14;11509:25;11491:43;;11625:16;11622:1;11615:27;11750:16;11744:4;11737;11734:1;11730:12;11715:52;12084:16;12077:24;;;;12103:4;12073:35;12110:18;12069:60;;9766:4;9759:12;9693:2450;;;-1:-1:-1;12249:4:0;12242:15;-1:-1:-1;8478:3795:0;;;-1:-1:-1;;;;;8478:3795:0:o;7862:879:6:-;8426:4;8420:11;;8487:16;8477:27;;8264:15;8531:4;8524:12;;8517:30;8307:18;8567:12;;;8560:33;;;;8627:9;8620:4;8613:12;;8606:31;8671:9;8664:4;8657:12;;8650:31;8720:4;8707:18;;;7862:879::o;8821:340::-;9091:9;8935:14;9088:28;9121:9;8980:11;9118:25;9084:60;9077:68;;8821:340::o;14:423:12:-;56:3;94:5;88:12;121:6;116:3;109:19;146:1;156:162;170:6;167:1;164:13;156:162;;;232:4;288:13;;;284:22;;278:29;260:11;;;256:20;;249:59;185:12;156:162;;;160:3;363:1;356:4;347:6;342:3;338:16;334:27;327:38;426:4;419:2;415:7;410:2;402:6;398:15;394:29;389:3;385:39;381:50;374:57;;;14:423;;;;:::o;442:220::-;591:2;580:9;573:21;554:4;611:45;652:2;641:9;637:18;629:6;611:45;:::i;667:162::-;733:5;778:3;769:6;764:3;760:16;756:26;753:46;;;795:1;792;785:12;834:347;885:8;895:6;949:3;942:4;934:6;930:17;926:27;916:55;;967:1;964;957:12;916:55;-1:-1:-1;990:20:12;;-1:-1:-1;;;;;1022:30:12;;1019:50;;;1065:1;1062;1055:12;1019:50;1102:4;1094:6;1090:17;1078:29;;1154:3;1147:4;1138:6;1130;1126:19;1122:30;1119:39;1116:59;;;1171:1;1168;1161:12;1116:59;834:347;;;;;:::o;1186:173::-;1254:20;;-1:-1:-1;;;;;1303:31:12;;1293:42;;1283:70;;1349:1;1346;1339:12;1283:70;1186:173;;;:::o;1364:1112::-;1513:6;1521;1529;1537;1545;1553;1561;1614:3;1602:9;1593:7;1589:23;1585:33;1582:53;;;1631:1;1628;1621:12;1582:53;1671:9;1658:23;-1:-1:-1;;;;;1741:2:12;1733:6;1730:14;1727:34;;;1757:1;1754;1747:12;1727:34;1780:73;1845:7;1836:6;1825:9;1821:22;1780:73;:::i;:::-;1770:83;;1906:2;1895:9;1891:18;1878:32;1862:48;;1935:2;1925:8;1922:16;1919:36;;;1951:1;1948;1941:12;1919:36;1990:60;2042:7;2031:8;2020:9;2016:24;1990:60;:::i;:::-;2069:8;;-1:-1:-1;1964:86:12;-1:-1:-1;1964:86:12;;-1:-1:-1;2123:38:12;2157:2;2142:18;;2123:38;:::i;:::-;2113:48;;2214:2;2203:9;2199:18;2186:32;2170:48;;2243:2;2233:8;2230:16;2227:36;;;2259:1;2256;2249:12;2227:36;;2298:60;2350:7;2339:8;2328:9;2324:24;2298:60;:::i;:::-;2377:8;;-1:-1:-1;2272:86:12;-1:-1:-1;2431:39:12;;-1:-1:-1;2465:3:12;2450:19;;2431:39;:::i;:::-;2421:49;;1364:1112;;;;;;;;;;:::o;2481:591::-;2532:3;2563;2595:5;2589:12;2622:6;2617:3;2610:19;2648:4;2677:2;2672:3;2668:12;2661:19;;2733:2;2723:6;2720:1;2716:14;2709:5;2705:26;2701:35;2770:2;2763:5;2759:14;2791:1;2801:245;2815:6;2812:1;2809:13;2801:245;;;2902:2;2898:7;2890:5;2884:4;2880:16;2876:30;2871:3;2864:43;2928:38;2961:4;2952:6;2946:13;2928:38;:::i;:::-;3024:12;;;;2920:46;-1:-1:-1;2989:15:12;;;;2837:1;2830:9;2801:245;;;-1:-1:-1;3062:4:12;;2481:591;-1:-1:-1;;;;;;;2481:591:12:o;3077:374::-;-1:-1:-1;;;;;3302:32:12;;3284:51;;3371:2;3366;3351:18;;3344:30;;;-1:-1:-1;;3391:54:12;;3426:18;;3418:6;3391:54;:::i;3456:675::-;3567:6;3575;3583;3636:2;3624:9;3615:7;3611:23;3607:32;3604:52;;;3652:1;3649;3642:12;3604:52;3692:9;3679:23;-1:-1:-1;;;;;3762:2:12;3754:6;3751:14;3748:34;;;3778:1;3775;3768:12;3748:34;3801:73;3866:7;3857:6;3846:9;3842:22;3801:73;:::i;:::-;3791:83;;3927:2;3916:9;3912:18;3899:32;3883:48;;3956:2;3946:8;3943:16;3940:36;;;3972:1;3969;3962:12;3940:36;;4011:60;4063:7;4052:8;4041:9;4037:24;4011:60;:::i;:::-;3456:675;;4090:8;;-1:-1:-1;3985:86:12;;-1:-1:-1;;;;3456:675:12:o;4136:367::-;4199:8;4209:6;4263:3;4256:4;4248:6;4244:17;4240:27;4230:55;;4281:1;4278;4271:12;4230:55;-1:-1:-1;4304:20:12;;-1:-1:-1;;;;;4336:30:12;;4333:50;;;4379:1;4376;4369:12;4333:50;4416:4;4408:6;4404:17;4392:29;;4476:3;4469:4;4459:6;4456:1;4452:14;4444:6;4440:27;4436:38;4433:47;4430:67;;;4493:1;4490;4483:12;4508:511;4603:6;4611;4619;4672:2;4660:9;4651:7;4647:23;4643:32;4640:52;;;4688:1;4685;4678:12;4640:52;4711:29;4730:9;4711:29;:::i;:::-;4701:39;;4791:2;4780:9;4776:18;4763:32;-1:-1:-1;;;;;4810:6:12;4807:30;4804:50;;;4850:1;4847;4840:12;4804:50;4889:70;4951:7;4942:6;4931:9;4927:22;4889:70;:::i;5024:642::-;5189:2;5241:21;;;5311:13;;5214:18;;;5333:22;;;5160:4;;5189:2;5412:15;;;;5386:2;5371:18;;;5160:4;5455:185;5469:6;5466:1;5463:13;5455:185;;;5544:13;;5537:21;5530:29;5518:42;;5615:15;;;;5580:12;;;;5491:1;5484:9;5455:185;;;-1:-1:-1;5657:3:12;;5024:642;-1:-1:-1;;;;;;5024:642:12:o;5853:437::-;5939:6;5947;6000:2;5988:9;5979:7;5975:23;5971:32;5968:52;;;6016:1;6013;6006:12;5968:52;6056:9;6043:23;-1:-1:-1;;;;;6081:6:12;6078:30;6075:50;;;6121:1;6118;6111:12;6075:50;6160:70;6222:7;6213:6;6202:9;6198:22;6160:70;:::i;:::-;6249:8;;6134:96;;-1:-1:-1;5853:437:12;-1:-1:-1;;;;5853:437:12:o;6295:557::-;6383:6;6391;6399;6407;6460:2;6448:9;6439:7;6435:23;6431:32;6428:52;;;6476:1;6473;6466:12;6428:52;6499:29;6518:9;6499:29;:::i;:::-;6489:39;;6579:2;6568:9;6564:18;6551:32;-1:-1:-1;;;;;6598:6:12;6595:30;6592:50;;;6638:1;6635;6628:12;6592:50;6677:58;6727:7;6718:6;6707:9;6703:22;6677:58;:::i;:::-;6754:8;;-1:-1:-1;6651:84:12;-1:-1:-1;6808:38:12;;-1:-1:-1;6842:2:12;6827:18;;6808:38;:::i;:::-;6798:48;;6295:557;;;;;;;:::o;6857:328::-;6934:6;6942;6950;7003:2;6991:9;6982:7;6978:23;6974:32;6971:52;;;7019:1;7016;7009:12;6971:52;7042:29;7061:9;7042:29;:::i;:::-;7032:39;;7090:38;7124:2;7113:9;7109:18;7090:38;:::i;:::-;7080:48;;7175:2;7164:9;7160:18;7147:32;7137:42;;6857:328;;;;;:::o;7479:435::-;7532:3;7570:5;7564:12;7597:6;7592:3;7585:19;7623:4;7652:2;7647:3;7643:12;7636:19;;7689:2;7682:5;7678:14;7710:1;7720:169;7734:6;7731:1;7728:13;7720:169;;;7795:13;;7783:26;;7829:12;;;;7864:15;;;;7756:1;7749:9;7720:169;;;-1:-1:-1;7905:3:12;;7479:435;-1:-1:-1;;;;;7479:435:12:o;7919:920::-;8325:3;8320;8316:13;8308:6;8304:26;8293:9;8286:45;8367:3;8362:2;8351:9;8347:18;8340:31;8267:4;8394:46;8435:3;8424:9;8420:19;8412:6;8394:46;:::i;:::-;8488:9;8480:6;8476:22;8471:2;8460:9;8456:18;8449:50;8522:33;8548:6;8540;8522:33;:::i;:::-;8586:2;8571:18;;8564:34;;;-1:-1:-1;;;;;8635:32:12;;8629:3;8614:19;;8607:61;8655:3;8684:19;;8677:35;;;8749:22;;;8743:3;8728:19;;8721:51;8508:47;-1:-1:-1;8789:44:12;8508:47;8818:6;8789:44;:::i;:::-;8781:52;7919:920;-1:-1:-1;;;;;;;;;;7919:920:12:o;8844:367::-;8935:6;8988:2;8976:9;8967:7;8963:23;8959:32;8956:52;;;9004:1;9001;8994:12;8956:52;9044:9;9031:23;-1:-1:-1;;;;;9069:6:12;9066:30;9063:50;;;9109:1;9106;9099:12;9063:50;9132:73;9197:7;9188:6;9177:9;9173:22;9132:73;:::i;9408:186::-;9467:6;9520:2;9508:9;9499:7;9495:23;9491:32;9488:52;;;9536:1;9533;9526:12;9488:52;9559:29;9578:9;9559:29;:::i;9599:127::-;9660:10;9655:3;9651:20;9648:1;9641:31;9691:4;9688:1;9681:15;9715:4;9712:1;9705:15;9731:127;9792:10;9787:3;9783:20;9780:1;9773:31;9823:4;9820:1;9813:15;9847:4;9844:1;9837:15;9863:443;10052:2;10034:21;;;10071:18;;10064:34;;;-1:-1:-1;;;;;;10110:31:12;;10107:51;;;10154:1;10151;10144:12;10107:51;10188:6;10185:1;10181:14;10245:6;10237;10232:2;10221:9;10217:18;10204:48;10273:22;;;;10297:2;10269:31;;9863:443;-1:-1:-1;;;9863:443:12:o;10311:556::-;10415:4;10421:6;10481:11;10468:25;10575:2;10571:7;10560:8;10544:14;10540:29;10536:43;10516:18;10512:68;10502:96;;10594:1;10591;10584:12;10502:96;10621:33;;10673:20;;;-1:-1:-1;;;;;;10705:30:12;;10702:50;;;10748:1;10745;10738:12;10702:50;10781:4;10769:17;;-1:-1:-1;10832:1:12;10828:14;;;10812;10808:35;10798:46;;10795:66;;;10857:1;10854;10847:12;10872:521;10949:4;10955:6;11015:11;11002:25;11109:2;11105:7;11094:8;11078:14;11074:29;11070:43;11050:18;11046:68;11036:96;;11128:1;11125;11118:12;11036:96;11155:33;;11207:20;;;-1:-1:-1;;;;;;11239:30:12;;11236:50;;;11282:1;11279;11272:12;11236:50;11315:4;11303:17;;-1:-1:-1;11346:14:12;11342:27;;;11332:38;;11329:58;;;11383:1;11380;11373:12;11398:271;11581:6;11573;11568:3;11555:33;11537:3;11607:16;;11632:13;;;11607:16;11398:271;-1:-1:-1;11398:271:12:o;11674:543::-;11892:13;;11835:3;;11866;;11945:4;11972:15;;;11835:3;12015:175;12029:6;12026:1;12023:13;12015:175;;;12092:13;;12078:28;;12128:14;;;;12165:15;;;;12051:1;12044:9;12015:175;;;-1:-1:-1;12206:5:12;;11674:543;-1:-1:-1;;;;;;11674:543:12:o;12772:551::-;12943:3;12974;13021:6;12943:3;13055:241;13069:6;13066:1;13063:13;13055:241;;;-1:-1:-1;;;;;13136:26:12;13155:6;13136:26;:::i;:::-;13132:52;13118:67;;13208:4;13234:14;;;;13271:15;;;;;13091:1;13084:9;13055:241;;;-1:-1:-1;13312:5:12;;12772:551;-1:-1:-1;;;;;12772:551:12:o;14428:261::-;14607:2;14596:9;14589:21;14570:4;14627:56;14679:2;14668:9;14664:18;14656:6;14627:56;:::i;14902:266::-;14990:6;14985:3;14978:19;15042:6;15035:5;15028:4;15023:3;15019:14;15006:43;-1:-1:-1;15094:1:12;15069:16;;;15087:4;15065:27;;;15058:38;;;;15150:2;15129:15;;;-1:-1:-1;;15125:29:12;15116:39;;;15112:50;;14902:266::o;15173:2076::-;15622:3;15611:9;15604:22;15585:4;15649:62;15706:3;15695:9;15691:19;15683:6;15675;15649:62;:::i;:::-;15768:22;;;15730:2;15748:18;;;15741:50;;;;15826:22;;;15902:6;;15864:15;;15926:1;15936:208;15950:6;15947:1;15944:13;15936:208;;;-1:-1:-1;;;;;16015:26:12;16034:6;16015:26;:::i;:::-;16011:52;15999:65;;16119:15;;;;16084:12;;;;15972:1;15965:9;15936:208;;;-1:-1:-1;16180:19:12;;;16175:2;16160:18;;16153:47;16234:19;;;16271:12;;;;-1:-1:-1;16323:1:12;16319:14;;;16310:24;;16306:33;;16364:6;16390:1;16400:725;16416:6;16411:3;16408:15;16400:725;;;16487:16;;;-1:-1:-1;;16483:30:12;16469:45;;16553:22;;16630:14;16626:27;;;-1:-1:-1;;16622:41:12;16598:66;;16588:94;;16678:1;16675;16668:12;16588:94;16708:31;;16813:14;;;;16766:19;-1:-1:-1;;;;;16843:30:12;;16840:50;;;16886:1;16883;16876:12;16840:50;16939:6;16923:14;16919:27;16910:7;16906:41;16903:61;;;16960:1;16957;16950:12;16903:61;16987:50;17030:6;17022;17013:7;16987:50;:::i;:::-;17101:14;;;;16977:60;-1:-1:-1;;;17062:17:12;;;;16442:1;16433:11;16400:725;;;16404:3;;17173:9;17165:6;17161:22;17156:2;17145:9;17141:18;17134:50;17201:42;17236:6;17228;17201:42;:::i;:::-;17193:50;15173:2076;-1:-1:-1;;;;;;;;;;;;;15173:2076:12:o

Swarm Source

ipfs://d594684cddf3261cd3a8d49bc981d492299a30b7d35d1bd5669ccd0bcc4c29dd

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.