ETH Price: $3,650.20 (+1.97%)

Contract

0x16b727a2Fc9322C724F4Bc562910c99a5edA5084
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

Advanced mode:
Parent Transaction Hash Block From To
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ScriptyBuilder

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 500 runs

Other Settings:
default evmVersion
File 1 of 6 : ScriptyBuilder.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

///////////////////////////////////////////////////////////
// ░██████╗░█████╗░██████╗░██╗██████╗░████████╗██╗░░░██╗ //
// ██╔════╝██╔══██╗██╔══██╗██║██╔══██╗╚══██╔══╝╚██╗░██╔╝ //
// ╚█████╗░██║░░╚═╝██████╔╝██║██████╔╝░░░██║░░░░╚████╔╝░ //
// ░╚═══██╗██║░░██╗██╔══██╗██║██╔═══╝░░░░██║░░░░░╚██╔╝░░ //
// ██████╔╝╚█████╔╝██║░░██║██║██║░░░░░░░░██║░░░░░░██║░░░ //
// ╚═════╝░░╚════╝░╚═╝░░╚═╝╚═╝╚═╝░░░░░░░░╚═╝░░░░░░╚═╝░░░ //
///////////////////////////////////////////////////////////

/**
  @title A generic HTML builder that fetches and assembles given JS requests.
  @author @0xthedude
  @author @xtremetom

  Special thanks to @cxkoda and @frolic
*/

import {DynamicBuffer} from "./utils/DynamicBuffer.sol";
import {AddressChunks} from "./utils/AddressChunks.sol";

import {IScriptyBuilder, InlineScriptRequest, WrappedScriptRequest} from "./IScriptyBuilder.sol";
import {IScriptyStorage} from "./IScriptyStorage.sol";
import {IContractScript} from "./IContractScript.sol";

contract ScriptyBuilder is IScriptyBuilder {
    using DynamicBuffer for bytes;

    // <html>,
    // raw
    // 6 bytes
    bytes public constant HTML_TAG_RAW = "<html>";
    // url encoded
    // 21 bytes
    bytes public constant HTML_TAG_URL_SAFE = "data%3Atext%2Fhtml%2C";

    // <body style='margin:0;'>
    // 24 bytes
    bytes public constant HTML_BODY_OPEN_RAW = "<body style='margin:0;'>";
    // url encoded
    // 56 bytes
    bytes public constant HTML_BODY_OPEN_URL_SAFE =
        "%253Cbody%2520style%253D%2527margin%253A0%253B%2527%253E";

    // </body></html>
    // 14 bytes
    bytes public constant HTML_BODY_CLOSED_RAW = "</body></html>";
    // 19 bytes
    bytes public constant HTML_BODY_CLOSED_URL_SAFE = "%253C%252Fbody%253E";

    // HTML_TAG_RAW + HTML_BODY_OPEN_RAW + HTML_BODY_CLOSED_RAW
    uint256 public constant URLS_RAW_BYTES = 44;

    // HTML_TAG_URL_SAFE + HTML_BODY_OPEN_URL_SAFE + HTML_BODY_CLOSED_URL_SAFE
    uint256 public constant URLS_SAFE_BYTES = 96;

    // <script></script>
    uint256 public constant SCRIPT_INLINE_BYTES = 17;

    // data:text/html;base64,
    uint256 public constant HTML_BASE64_DATA_URI_BYTES = 22;

    // =============================================================
    //                      RAW HTML GETTERS
    // =============================================================

    /**
     * @notice Get requested scripts housed in <body> with custom wrappers
     * @dev Your requested scripts are returned in the following format:
     *      <html>
     *          <head></head>
     *          <body style='margin:0;'>
     *              [wrapPrefix[0]]{request[0]}[wrapSuffix[0]]
     *              [wrapPrefix[1]]{request[1]}[wrapSuffix[1]]
     *              ...
     *              [wrapPrefix[n]]{request[n]}[wrapSuffix[n]]
     *          </body>
     *      </html>
     * @param requests - Array of WrappedScriptRequests
     * @param bufferSize - Total buffer size of all requested scripts
     * @return Full html wrapped scripts
     */
    function getHTMLWrapped(
        WrappedScriptRequest[] calldata requests,
        uint256 bufferSize
    ) public view returns (bytes memory) {
        uint256 length = requests.length;
        if (length == 0) revert InvalidRequestsLength();

        bytes memory htmlFile = DynamicBuffer.allocate(bufferSize);
        htmlFile.appendSafe(HTML_TAG_RAW);
        htmlFile.appendSafe(HTML_BODY_OPEN_RAW);

        bytes memory wrapPrefix;
        bytes memory wrapSuffix;
        WrappedScriptRequest memory request;
        uint256 i;

        unchecked {
            do {
                request = requests[i];
                (wrapPrefix, wrapSuffix) = wrapPrefixAndSuffixFor(request);
                htmlFile.appendSafe(wrapPrefix);

                htmlFile.appendSafe(
                    fetchScript(
                        request.name,
                        request.contractAddress,
                        request.contractData,
                        request.scriptContent
                    )
                );

                htmlFile.appendSafe(wrapSuffix);
            } while (++i < length);
        }

        htmlFile.appendSafe(HTML_BODY_CLOSED_RAW);
        return htmlFile;
    }

    /**
     * @notice Get requested scripts housed in URL Safe wrappers
     * @dev Any wrapper type 0 scripts are converted to base64 and wrapped
     *      with <script src="data:text/javascript;base64,[SCRIPT]"></script>
     *
     *      [WARNING]: Large non-base64 libraries that need base64 encoding
     *      carry a high risk of causing a gas out. Highly advised the use
     *      of base64 encoded scripts where possible
     *
     *      Your requested scripts are returned in the following format:
     *      <html>
     *          <head></head>
     *          <body style='margin:0;'>
     *              [wrapPrefix[0]]{request[0]}[wrapSuffix[0]]
     *              [wrapPrefix[1]]{request[1]}[wrapSuffix[1]]
     *              ...
     *              [wrapPrefix[n]]{request[n]}[wrapSuffix[n]]
     *          </body>
     *      </html>
     * @param requests - Array of WrappedScriptRequests
     * @param bufferSize - Total buffer size of all requested scripts
     * @return Full URL Safe wrapped scripts
     */
    function getHTMLWrappedURLSafe(
        WrappedScriptRequest[] calldata requests,
        uint256 bufferSize
    ) public view returns (bytes memory) {
        uint256 length = requests.length;
        if (length == 0) revert InvalidRequestsLength();

        bytes memory htmlFile = DynamicBuffer.allocate(bufferSize);
        htmlFile.appendSafe(HTML_TAG_URL_SAFE);
        htmlFile.appendSafe(HTML_BODY_OPEN_URL_SAFE);

        bytes memory wrapPrefix;
        bytes memory wrapSuffix;
        WrappedScriptRequest memory request;
        uint256 i;

        // Iterate through scripts and convert any non base64 into base64
        // Dont touch any existing base64
        // Wrap code in appropriate urlencoded tags
        unchecked {
            do {
                request = requests[i];
                (wrapPrefix, wrapSuffix) = wrapURLSafePrefixAndSuffixFor(
                    request
                );
                htmlFile.appendSafe(wrapPrefix);

                // convert raw code into base64
                if (request.wrapType == 0) {
                    htmlFile.appendSafeBase64(
                        fetchScript(
                            request.name,
                            request.contractAddress,
                            request.contractData,
                            request.scriptContent
                        ),
                        false,
                        false
                    );
                } else {
                    htmlFile.appendSafe(
                        fetchScript(
                            request.name,
                            request.contractAddress,
                            request.contractData,
                            request.scriptContent
                        )
                    );
                }
                htmlFile.appendSafe(wrapSuffix);
            } while (++i < length);
        }

        htmlFile.appendSafe(HTML_BODY_CLOSED_URL_SAFE);
        return htmlFile;
    }

    /**
     * @notice Get requested scripts housed in <body> all wrapped in <script></script>
     * @dev Your requested scripts are returned in the following format:
     *      <html>
     *          <head></head>
     *          <body style='margin:0;'>
     *              <script>
     *                  {request[0]}
     *                  {request[1]}
     *                  ...
     *                  {request[n]}
     *              </script>
     *          </body>
     *      </html>
     * @param requests - Array of InlineScriptRequest
     * @param bufferSize - Total buffer size of all requested scripts
     * @return Full html wrapped scripts
     */
    function getHTMLInline(
        InlineScriptRequest[] calldata requests,
        uint256 bufferSize
    ) public view returns (bytes memory) {
        uint256 length = requests.length;
        if (length == 0) revert InvalidRequestsLength();

        bytes memory htmlFile = DynamicBuffer.allocate(bufferSize);
        htmlFile.appendSafe(HTML_TAG_RAW);
        htmlFile.appendSafe(HTML_BODY_OPEN_RAW);
        htmlFile.appendSafe("<script>");

        InlineScriptRequest memory request;
        uint256 i;

        unchecked {
            do {
                request = requests[i];
                htmlFile.appendSafe(
                    fetchScript(
                        request.name,
                        request.contractAddress,
                        request.contractData,
                        request.scriptContent
                    )
                );
            } while (++i < length);
        }

        htmlFile.appendSafe("</script>");
        htmlFile.appendSafe(HTML_BODY_CLOSED_RAW);
        return htmlFile;
    }

    // =============================================================
    //                      ENCODED HTML GETTERS
    // =============================================================

    /**
     * @notice Get {getHTMLWrapped} and base64 encode it
     * @param requests - Array of WrappedScriptRequests
     * @param bufferSize - Total buffer size of all requested scripts
     * @return Full html wrapped scripts, base64 encoded
     */
    function getEncodedHTMLWrapped(
        WrappedScriptRequest[] calldata requests,
        uint256 bufferSize
    ) public view returns (bytes memory) {
        unchecked {
            bytes memory rawHTML = getHTMLWrapped(requests, bufferSize);

            uint256 sizeForEncoding = HTML_BASE64_DATA_URI_BYTES +
                sizeForBase64Encoding(rawHTML.length);

            bytes memory htmlFile = DynamicBuffer.allocate(sizeForEncoding);
            htmlFile.appendSafe("data:text/html;base64,");
            htmlFile.appendSafeBase64(rawHTML, false, false);
            return htmlFile;
        }
    }

    /**
     * @notice Get {getHTMLInline} and base64 encode it
     * @param requests - Array of InlineScriptRequests
     * @param bufferSize - Total buffer size of all requested scripts
     * @return Full html wrapped scripts, base64 encoded
     */
    function getEncodedHTMLInline(
        InlineScriptRequest[] calldata requests,
        uint256 bufferSize
    ) public view returns (bytes memory) {
        unchecked {
            bytes memory rawHTML = getHTMLInline(requests, bufferSize);

            uint256 sizeForEncoding = HTML_BASE64_DATA_URI_BYTES +
                sizeForBase64Encoding(rawHTML.length);

            bytes memory htmlFile = DynamicBuffer.allocate(sizeForEncoding);
            htmlFile.appendSafe("data:text/html;base64,");
            htmlFile.appendSafeBase64(rawHTML, false, false);

            return htmlFile;
        }
    }

    // =============================================================
    //                      STRING UTILITIES
    // =============================================================

    /**
     * @notice Convert {getHTMLWrapped} output to a string
     * @param requests - Array of WrappedScriptRequests
     * @param bufferSize - Total buffer size of all requested scripts
     * @return {getHTMLWrapped} as a string
     */
    function getHTMLWrappedString(
        WrappedScriptRequest[] calldata requests,
        uint256 bufferSize
    ) public view returns (string memory) {
        return string(getHTMLWrapped(requests, bufferSize));
    }

    /**
     * @notice Convert {getHTMLWrappedURLSafe} output to a string
     * @param requests - Array of WrappedScriptRequests
     * @param bufferSize - Total buffer size of all requested scripts
     * @return {getHTMLWrappedURLSafe} as a string
     */
    function getURLSafeHTMLWrappedString(
        WrappedScriptRequest[] calldata requests,
        uint256 bufferSize
    ) public view returns (string memory) {
        return string(getHTMLWrappedURLSafe(requests, bufferSize));
    }

    /**
     * @notice Convert {getHTMLInline} output to a string
     * @param requests - Array of InlineScriptRequests
     * @param bufferSize - Total buffer size of all requested scripts
     * @return {getHTMLInline} as a string
     */
    function getHTMLInlineString(
        InlineScriptRequest[] calldata requests,
        uint256 bufferSize
    ) public view returns (string memory) {
        return string(getHTMLInline(requests, bufferSize));
    }

    /**
     * @notice Convert {getEncodedHTMLWrapped} output to a string
     * @param requests - Array of WrappedScriptRequests
     * @param bufferSize - Total buffer size of all requested scripts
     * @return {getEncodedHTMLWrapped} as a string
     */
    function getEncodedHTMLWrappedString(
        WrappedScriptRequest[] calldata requests,
        uint256 bufferSize
    ) public view returns (string memory) {
        return string(getEncodedHTMLWrapped(requests, bufferSize));
    }

    /**
     * @notice Convert {getEncodedHTMLInline} output to a string
     * @param requests - Array of InlineScriptRequests
     * @param bufferSize - Total buffer size of all requested scripts
     * @return {getEncodedHTMLInline} as a string
     */
    function getEncodedHTMLInlineString(
        InlineScriptRequest[] calldata requests,
        uint256 bufferSize
    ) public view returns (string memory) {
        return string(getEncodedHTMLInline(requests, bufferSize));
    }

    // =============================================================
    //                      OFF-CHAIN UTILITIES
    // =============================================================

    /**
     * @notice Get the buffer size of a single inline requested code
     * @param request - InlineScriptRequest data for code
     * @return Buffer size as an unit256
     */
    function getInlineScriptSize(InlineScriptRequest memory request)
        public
        view
        returns (uint256)
    {
        return
            fetchScript(
                request.name,
                request.contractAddress,
                request.contractData,
                request.scriptContent
            ).length;
    }

    /**
     * @notice Get the buffer size of a single wrapped requested code
     * @param request - WrappedScriptRequest data for code
     * @return Buffer size as an unit256
     */
    function getWrappedScriptSize(WrappedScriptRequest memory request)
        public
        view
        returns (uint256)
    {
        unchecked {
            (
                bytes memory wrapPrefix,
                bytes memory wrapSuffix
            ) = wrapPrefixAndSuffixFor(request);

            uint256 scriptSize = fetchScript(
                request.name,
                request.contractAddress,
                request.contractData,
                request.scriptContent
            ).length;

            return wrapPrefix.length + wrapSuffix.length + scriptSize;
        }
    }

    /**
     * @notice Get the buffer size of a single wrapped requested code
     * @dev If the script is of wrapper type 0, we get buffer size for
     *      base64 encoded version.
     * @param request - WrappedScriptRequest data for code
     * @return Buffer size as an unit256
     */
    function getURLSafeWrappedScriptSize(WrappedScriptRequest memory request)
        public
        view
        returns (uint256)
    {
        unchecked {
            (
                bytes memory wrapPrefix,
                bytes memory wrapSuffix
            ) = wrapURLSafePrefixAndSuffixFor(request);

            uint256 scriptSize = fetchScript(
                request.name,
                request.contractAddress,
                request.contractData,
                request.scriptContent
            ).length;

            if (request.wrapType == 0) {
                scriptSize = sizeForBase64Encoding(scriptSize);
            }

            return wrapPrefix.length + wrapSuffix.length + scriptSize;
        }
    }

    /**
     * @notice Get the buffer size of an array of html wrapped inline scripts
     * @param requests - InlineScriptRequests data for code
     * @return Buffer size as an unit256
     */
    function getBufferSizeForHTMLInline(InlineScriptRequest[] calldata requests)
        public
        view
        returns (uint256)
    {
        uint256 size;
        uint256 i;
        uint256 length = requests.length;
        InlineScriptRequest memory request;

        unchecked {
            if (length > 0) {
                do {
                    request = requests[i];
                    size += getInlineScriptSize(request);
                } while (++i < length);
            }
            return size + URLS_RAW_BYTES + SCRIPT_INLINE_BYTES;
        }
    }

    /**
     * @notice Get the buffer size of an array of html wrapped, wrapped scripts
     * @param requests - WrappedScriptRequests data for code
     * @return Buffer size as an unit256
     */
    function getBufferSizeForHTMLWrapped(
        WrappedScriptRequest[] calldata requests
    ) public view returns (uint256) {
        uint256 size;
        uint256 i;
        uint256 length = requests.length;
        WrappedScriptRequest memory request;

        unchecked {
            if (length > 0) {
                do {
                    request = requests[i];
                    size += getWrappedScriptSize(request);
                } while (++i < length);
            }
            return size + URLS_RAW_BYTES;
        }
    }

    /**
     * @notice Get the buffer size of an array of URL safe html wrapped scripts
     * @param requests - WrappedScriptRequests data for code
     * @return Buffer size as an unit256
     */
    function getBufferSizeForURLSafeHTMLWrapped(
        WrappedScriptRequest[] calldata requests
    ) public view returns (uint256) {
        uint256 size;
        uint256 i;
        uint256 length = requests.length;
        WrappedScriptRequest memory request;

        unchecked {
            if (length > 0) {
                do {
                    request = requests[i];
                    size += getURLSafeWrappedScriptSize(request);
                } while (++i < length);
            }
            return size + URLS_SAFE_BYTES;
        }
    }

    /**
     * @notice Get the buffer size for encoded HTML inline scripts
     * @param requests - InlineScriptRequests data for code
     * @return Buffer size as an unit256
     */
    function getBufferSizeForEncodedHTMLInline(
        InlineScriptRequest[] calldata requests
    ) public view returns (uint256) {
        unchecked {
            uint256 size = getBufferSizeForHTMLInline(requests);
            return HTML_BASE64_DATA_URI_BYTES + sizeForBase64Encoding(size);
        }
    }

    /**
     * @notice Get the buffer size for encoded HTML inline scripts
     * @param requests - InlineScriptRequests data for code
     * @return Buffer size as an unit256
     */
    function getBufferSizeForEncodedHTMLWrapped(
        WrappedScriptRequest[] calldata requests
    ) public view returns (uint256) {
        unchecked {
            uint256 size = getBufferSizeForHTMLWrapped(requests);
            return HTML_BASE64_DATA_URI_BYTES + sizeForBase64Encoding(size);
        }
    }

    // =============================================================
    //                           INTERNAL
    // =============================================================

    /**
     * @notice Grabs requested script from storage
     * @param scriptName - Name given to the script. Eg: threejs.min.js_r148
     * @param storageAddress - Address of scripty storage contract
     * @param contractData - Arbitrary data to be passed to storage
     * @param scriptContent - Small custom script to inject
     * @return Requested script as bytes
     */
    function fetchScript(
        string memory scriptName,
        address storageAddress,
        bytes memory contractData,
        bytes memory scriptContent
    ) internal view returns (bytes memory) {
        if (scriptContent.length > 0) {
            return scriptContent;
        }

        return
            IContractScript(storageAddress).getScript(scriptName, contractData);
    }

    /**
     * @notice Grab script wrapping based on script type
     * @dev
     *      wrapType: 0:
     *          <script>[SCRIPT]</script>
     *
     *      wrapType: 1:
     *          <script src="data:text/javascript;base64,[SCRIPT]"></script>
     *
     *      wrapType: 2:
     *          <script type="text/javascript+gzip" src="data:text/javascript;base64,[SCRIPT]"></script>
     *
     *      wrapType: 3
     *          <script type="text/javascript+png" name="[NAME]" src="data:text/javascript;base64,[SCRIPT]"></script>
     *
     *      wrapType: 4 or any other:
     *          [wrapPrefix][scriptContent or scriptFromContract][wrapSuffix]
     *
     *
     *      [IMPORTANT NOTE]: The tags `text/javascript+gzip` and `text/javascript+png` are used to identify scripts
     *      during decompression
     *
     * @param request - WrappedScriptRequest data for code
     * @return (prefix, suffix) - Type specific prefix and suffix as a tuple
     */
    function wrapPrefixAndSuffixFor(WrappedScriptRequest memory request)
    internal
    pure
    returns (bytes memory, bytes memory)
    {
        if (request.wrapType == 0) {
            return ("<script>", "</script>");
        } else if (request.wrapType == 1) {
            return ('<script src="data:text/javascript;base64,', '"></script>');
        } else if (request.wrapType == 2) {
            return (
            '<script type="text/javascript+gzip" src="data:text/javascript;base64,',
            '"></script>'
            );
        } else if (request.wrapType == 3) {
            return (
            '<script type="text/javascript+png" src="data:text/javascript;base64,',
            '"></script>'
            );
        }
        return (request.wrapPrefix, request.wrapSuffix);
    }

    /**
     * @notice Grab URL safe script wrapping based on script type
     * @dev
     *      wrapType: 0:
     *      wrapType: 1:
     *          <script src="data:text/javascript;base64,[SCRIPT]"></script>
     *
     *      wrapType: 2:
     *          <script type="text/javascript+gzip" src="data:text/javascript;base64,[SCRIPT]"></script>
     *
     *      wrapType: 3
     *          <script type="text/javascript+png" name="[NAME]" src="data:text/javascript;base64,[SCRIPT]"></script>
     *
     *      wrapType: 4 or any other:
     *          [wrapPrefix][scriptContent or scriptFromContract][wrapSuffix]
     *
     *
     *      [IMPORTANT NOTE]: The tags `text/javascript+gzip` and `text/javascript+png` are used to identify scripts
     *      during decompression
     *
     * @param request - WrappedScriptRequest data for code
     * @return (prefix, suffix) - Type specific prefix and suffix as a tuple
     */
    function wrapURLSafePrefixAndSuffixFor(WrappedScriptRequest memory request)
    internal
    pure
    returns (bytes memory, bytes memory)
    {
        if (request.wrapType <= 1) {
            // <script src="data:text/javascript;base64,
            // "></script>
            return (
            "%253Cscript%2520src%253D%2522data%253Atext%252Fjavascript%253Bbase64%252C",
            "%2522%253E%253C%252Fscript%253E"
            );
        } else if (request.wrapType == 2) {
            // <script type="text/javascript+gzip" src="data:text/javascript;base64,
            // "></script>
            return (
            "%253Cscript%2520type%253D%2522text%252Fjavascript%252Bgzip%2522%2520src%253D%2522data%253Atext%252Fjavascript%253Bbase64%252C",
            "%2522%253E%253C%252Fscript%253E"
            );
        } else if (request.wrapType == 3) {
            // <script type="text/javascript+png" src="data:text/javascript;base64,
            // "></script>
            return (
            "%253Cscript%2520type%253D%2522text%252Fjavascript%252Bpng%2522%2520src%253D%2522data%253Atext%252Fjavascript%253Bbase64%252C",
            "%2522%253E%253C%252Fscript%253E"
            );
        }
        return (request.wrapPrefix, request.wrapSuffix);
    }

    /**
     * @notice Calculate the buffer size post base64 encoding
     * @param value - Starting buffer size
     * @return Final buffer size as uint256
     */
    function sizeForBase64Encoding(uint256 value)
        internal
        pure
        returns (uint256)
    {
        unchecked {
            return 4 * ((value + 2) / 3);
        }
    }
}

File 2 of 6 : IScriptyBuilder.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

///////////////////////////////////////////////////////////
// ░██████╗░█████╗░██████╗░██╗██████╗░████████╗██╗░░░██╗ //
// ██╔════╝██╔══██╗██╔══██╗██║██╔══██╗╚══██╔══╝╚██╗░██╔╝ //
// ╚█████╗░██║░░╚═╝██████╔╝██║██████╔╝░░░██║░░░░╚████╔╝░ //
// ░╚═══██╗██║░░██╗██╔══██╗██║██╔═══╝░░░░██║░░░░░╚██╔╝░░ //
// ██████╔╝╚█████╔╝██║░░██║██║██║░░░░░░░░██║░░░░░░██║░░░ //
// ╚═════╝░░╚════╝░╚═╝░░╚═╝╚═╝╚═╝░░░░░░░░╚═╝░░░░░░╚═╝░░░ //
///////////////////////////////////////////////////////////

// =============================================================
//                            STRUCTS
// =============================================================

struct WrappedScriptRequest {
    string name;
    address contractAddress;
    bytes contractData;
    uint8 wrapType;
    bytes wrapPrefix;
    bytes wrapSuffix;
    bytes scriptContent;
}

struct InlineScriptRequest {
    string name;
    address contractAddress;
    bytes contractData;
    bytes scriptContent;
}

interface IScriptyBuilder {

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

    /**
     * @notice Error for, Invalid length of requests
     */
    error InvalidRequestsLength();

    // =============================================================
    //                      RAW HTML GETTERS
    // =============================================================

    /**
     * @notice Get requested scripts housed in <body> with custom wrappers
     * @dev Your requested scripts are returned in the following format:
     *      <html>
     *          <head></head>
     *          <body style='margin:0;'>
     *              [wrapPrefix[0]]{request[0]}[wrapSuffix[0]]
     *              [wrapPrefix[1]]{request[1]}[wrapSuffix[1]]
     *              ...
     *              [wrapPrefix[n]]{request[n]}[wrapSuffix[n]]
     *          </body>
     *      </html>
     * @param requests - Array of WrappedScriptRequests
     * @param bufferSize - Total buffer size of all requested scripts
     * @return Full html wrapped scripts
     */
    function getHTMLWrapped(
        WrappedScriptRequest[] calldata requests,
        uint256 bufferSize
    ) external view returns (bytes memory);

    /**
     * @notice Get requested scripts housed in URL Safe wrappers
     * @dev Any wrapper type 0 scripts are converted to base64 and wrapped
     *      with <script src="data:text/javascript;base64,[SCRIPT]"></script>
     *
     *      [WARNING]: Large non-base64 libraries that need base64 encoding
     *      carry a high risk of causing a gas out. Highly advised to use
     *      base64 encoded scripts where possible
     *
     *      Your requested scripts are returned in the following format:
     *      <html>
     *          <head></head>
     *          <body style='margin:0;'>
     *              [wrapPrefix[0]]{request[0]}[wrapSuffix[0]]
     *              [wrapPrefix[1]]{request[1]}[wrapSuffix[1]]
     *              ...
     *              [wrapPrefix[n]]{request[n]}[wrapSuffix[n]]
     *          </body>
     *      </html>
     * @param requests - Array of WrappedScriptRequests
     * @param bufferSize - Total buffer size of all requested scripts
     * @return Full URL Safe wrapped scripts
     */
    function getHTMLWrappedURLSafe(
        WrappedScriptRequest[] calldata requests,
        uint256 bufferSize
    ) external view returns (bytes memory);

    /**
     * @notice Get requested scripts housed in <body> all wrapped in <script></script>
     * @dev Your requested scripts are returned in the following format:
     *      <html>
     *          <head></head>
     *          <body style='margin:0;'>
     *              <script>
     *                  {request[0]}
     *                  {request[1]}
     *                  ...
     *                  {request[n]}
     *              </script>
     *          </body>
     *      </html>
     * @param requests - Array of InlineScriptRequest
     * @param bufferSize - Total buffer size of all requested scripts
     * @return Full html wrapped scripts
     */
    function getHTMLInline(
        InlineScriptRequest[] calldata requests,
        uint256 bufferSize
    ) external view returns (bytes memory);

    // =============================================================
    //                      ENCODED HTML GETTERS
    // =============================================================

    /**
     * @notice Get {getHTMLWrapped} and base64 encode it
     * @param requests - Array of WrappedScriptRequests
     * @param bufferSize - Total buffer size of all requested scripts
     * @return Full html wrapped scripts, base64 encoded
     */
    function getEncodedHTMLWrapped(
        WrappedScriptRequest[] calldata requests,
        uint256 bufferSize
    ) external view returns (bytes memory);

    /**
     * @notice Get {getHTMLInline} and base64 encode it
     * @param requests - Array of InlineScriptRequests
     * @param bufferSize - Total buffer size of all requested scripts
     * @return Full html wrapped scripts, base64 encoded
     */
    function getEncodedHTMLInline(
        InlineScriptRequest[] calldata requests,
        uint256 bufferSize
    ) external view returns (bytes memory);

    // =============================================================
    //                      STRING UTILITIES
    // =============================================================

    /**
     * @notice Convert {getHTMLWrapped} output to a string
     * @param requests - Array of WrappedScriptRequests
     * @param bufferSize - Total buffer size of all requested scripts
     * @return {getHTMLWrapped} as a string
     */
    function getHTMLWrappedString(
        WrappedScriptRequest[] calldata requests,
        uint256 bufferSize
    ) external view returns (string memory);

    /**
     * @notice Convert {getHTMLInline} output to a string
     * @param requests - Array of InlineScriptRequests
     * @param bufferSize - Total buffer size of all requested scripts
     * @return {getHTMLInline} as a string
     */
    function getHTMLInlineString(
        InlineScriptRequest[] calldata requests,
        uint256 bufferSize
    ) external view returns (string memory);

    /**
     * @notice Convert {getEncodedHTMLWrapped} output to a string
     * @param requests - Array of WrappedScriptRequests
     * @param bufferSize - Total buffer size of all requested scripts
     *                     before encoding.
     * @return {getEncodedHTMLWrapped} as a string
     */
    function getEncodedHTMLWrappedString(
        WrappedScriptRequest[] calldata requests,
        uint256 bufferSize
    ) external view returns (string memory);

    /**
     * @notice Convert {getEncodedHTMLInline} output to a string
     * @param requests - Array of InlineScriptRequests
     * @param bufferSize - Total buffer size of all requested scripts
     *                     before encoding.
     * @return {getEncodedHTMLInline} as a string
     */
    function getEncodedHTMLInlineString(
        InlineScriptRequest[] calldata requests,
        uint256 bufferSize
    ) external view returns (string memory);

    // =============================================================
    //                      OFF-CHAIN UTILITIES
    // =============================================================

    /**
     * @notice Get the buffer size of a single inline requested code
     * @param request - InlineScriptRequest data for code
     * @return Buffer size as an unit256
     */
    function getInlineScriptSize(InlineScriptRequest memory request)
        external
        view
        returns (uint256);

    /**
     * @notice Get the buffer size of a single wrapped requested code
     * @param request - WrappedScriptRequest data for code
     * @return Buffer size as an unit256
     */
    function getWrappedScriptSize(WrappedScriptRequest memory request)
        external
        view
        returns (uint256);

    /**
     * @notice Get the buffer size of a single wrapped requested code
     * @dev If the script is of wrapper type 0, we get buffer size for
     *      base64 encoded version.
     * @param request - WrappedScriptRequest data for code
     * @return Buffer size as an unit256
     */
    function getURLSafeWrappedScriptSize(WrappedScriptRequest memory request)
    external
    view
    returns (uint256);

    /**
     * @notice Get the buffer size of an array of html wrapped inline scripts
     * @param requests - InlineScriptRequests data for code
     * @return Buffer size as an unit256
     */
    function getBufferSizeForHTMLInline(InlineScriptRequest[] calldata requests)
        external
        view
        returns (uint256);

    /**
     * @notice Get the buffer size of an array of html wrapped, wrapped scripts
     * @param requests - WrappedScriptRequests data for code
     * @return Buffer size as an unit256
     */
    function getBufferSizeForHTMLWrapped(
        WrappedScriptRequest[] calldata requests
    ) external view returns (uint256);

    /**
     * @notice Get the buffer size of an array of URL safe html wrapped scripts
     * @param requests - WrappedScriptRequests data for code
     * @return Buffer size as an unit256
     */
    function getBufferSizeForURLSafeHTMLWrapped(
        WrappedScriptRequest[] calldata requests
    ) external view returns (uint256);
    
    /**
     * @notice Get the buffer size for encoded HTML inline scripts
     * @param requests - InlineScriptRequests data for code
     * @return Buffer size as an unit256
     */
    function getBufferSizeForEncodedHTMLInline(
        InlineScriptRequest[] calldata requests
    ) external view returns (uint256);

    /**
     * @notice Get the buffer size for encoded HTML inline scripts
     * @param requests - InlineScriptRequests data for code
     * @return Buffer size as an unit256
     */
    function getBufferSizeForEncodedHTMLWrapped(
        WrappedScriptRequest[] calldata requests
    ) external view returns (uint256);
}

File 3 of 6 : IContractScript.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

///////////////////////////////////////////////////////////
// ░██████╗░█████╗░██████╗░██╗██████╗░████████╗██╗░░░██╗ //
// ██╔════╝██╔══██╗██╔══██╗██║██╔══██╗╚══██╔══╝╚██╗░██╔╝ //
// ╚█████╗░██║░░╚═╝██████╔╝██║██████╔╝░░░██║░░░░╚████╔╝░ //
// ░╚═══██╗██║░░██╗██╔══██╗██║██╔═══╝░░░░██║░░░░░╚██╔╝░░ //
// ██████╔╝╚█████╔╝██║░░██║██║██║░░░░░░░░██║░░░░░░██║░░░ //
// ╚═════╝░░╚════╝░╚═╝░░╚═╝╚═╝╚═╝░░░░░░░░╚═╝░░░░░░╚═╝░░░ //
///////////////////////////////////////////////////////////

interface IContractScript {
    // =============================================================
    //                            GETTERS
    // =============================================================

    /**
     * @notice Get the full script
     * @param name - Name given to the script. Eg: threejs.min.js_r148
     * @param data - Arbitrary data to be passed to storage
     * @return script - Full script from merged chunks
     */
    function getScript(string calldata name, bytes memory data)
        external
        view
        returns (bytes memory script);
}

File 4 of 6 : IScriptyStorage.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

///////////////////////////////////////////////////////////
// ░██████╗░█████╗░██████╗░██╗██████╗░████████╗██╗░░░██╗ //
// ██╔════╝██╔══██╗██╔══██╗██║██╔══██╗╚══██╔══╝╚██╗░██╔╝ //
// ╚█████╗░██║░░╚═╝██████╔╝██║██████╔╝░░░██║░░░░╚████╔╝░ //
// ░╚═══██╗██║░░██╗██╔══██╗██║██╔═══╝░░░░██║░░░░░╚██╔╝░░ //
// ██████╔╝╚█████╔╝██║░░██║██║██║░░░░░░░░██║░░░░░░██║░░░ //
// ╚═════╝░░╚════╝░╚═╝░░╚═╝╚═╝╚═╝░░░░░░░░╚═╝░░░░░░╚═╝░░░ //
///////////////////////////////////////////////////////////

interface IScriptyStorage {
    // =============================================================
    //                            STRUCTS
    // =============================================================

    struct Script {
        bool isVerified;
        address owner;
        uint256 size;
        bytes details;
        address[] chunks;
    }

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

    /**
     * @notice Error for, The Script you are trying to create already exists
     */
    error ScriptExists();

    /**
     * @notice Error for, You dont have permissions to perform this action
     */
    error NotScriptOwner();

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

    /**
     * @notice Event for, Successful update of script verification status
     * @param name - Name given to the script. Eg: threejs.min.js_r148
     * @param isVerified - Verification status of the script
     */
    event ScriptVerificationUpdated(string indexed name, bool isVerified);

    /**
     * @notice Event for, Successful creation of a script
     * @param name - Name given to the script. Eg: threejs.min.js_r148
     * @param owner - Address of the script owner
     * @param details - Custom details of the script
     */
    event ScriptCreated(string indexed name, address owner, bytes details);

    /**
     * @notice Event for, Successful addition of script chunk
     * @param name - Name given to the script. Eg: threejs.min.js_r148
     * @param size - Bytes size of the chunk
     */
    event ChunkStored(string indexed name, uint256 size);

    /**
     * @notice Event for, Successful update of custom details
     * @param name - Name given to the script. Eg: threejs.min.js_r148
     * @param owner - Address of the script owner
     * @param details - Custom details of the script
     */
    event ScriptDetailsUpdated(
        string indexed name,
        address owner,
        bytes details
    );

    // =============================================================
    //                      MANAGEMENT OPERATIONS
    // =============================================================

    /**
     * @notice Create a new script
     * @param name - Name given to the script. Eg: threejs.min.js_r148
     * @param details - Any details the owner wishes to store about the script
     *
     * Emits an {ScriptCreated} event.
     */
    function createScript(string calldata name, bytes calldata details)
        external;

    /**
     * @notice Add a code chunk to the script
     * @param name - Name given to the script. Eg: threejs.min.js_r148
     * @param chunk - Next sequential code chunk
     *
     * Emits an {ChunkStored} event.
     */
    function addChunkToScript(string calldata name, bytes calldata chunk)
        external;

    /**
     * @notice Edit the script details
     * @param name - Name given to the script. Eg: threejs.min.js_r148
     * @param details - Any details the owner wishes to store about the script
     *
     * Emits an {ScriptDetailsUpdated} event.
     */
    function updateDetails(string calldata name, bytes calldata details)
        external;

    /**
     * @notice Update the verification status of the script
     * @param name - Name given to the script. Eg: threejs.min.js_r148
     * @param isVerified - The verification status
     *
     * Emits an {ScriptVerificationUpdated} event.
     */
    function updateScriptVerification(string calldata name, bool isVerified)
        external;
}

File 5 of 6 : AddressChunks.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

/**
 * @title AddressChunks
 * @author @xtremetom
 * @notice Reads chunk pointers and merges their values
 */
library AddressChunks {
    function mergeChunks(address[] memory chunks)
        internal
        view
        returns (bytes memory o_code)
    {
        unchecked {
            assembly {
                let len := mload(chunks)
                let totalSize := 0x20
                let size := 0
                o_code := mload(0x40)

                // loop through all chunk addresses
                // - get address
                // - get data size
                // - get code and add to o_code
                // - update total size
                let targetChunk := 0
                for {
                    let i := 0
                } lt(i, len) {
                    i := add(i, 1)
                } {
                    targetChunk := mload(add(chunks, add(0x20, mul(i, 0x20))))
                    size := sub(extcodesize(targetChunk), 1)
                    extcodecopy(targetChunk, add(o_code, totalSize), 1, size)
                    totalSize := add(totalSize, size)
                }

                // update o_code size
                mstore(o_code, sub(totalSize, 0x20))
                // store o_code
                mstore(0x40, add(o_code, and(add(totalSize, 0x1f), not(0x1f))))
            }
        }
    }
}

File 6 of 6 : DynamicBuffer.sol
// SPDX-License-Identifier: MIT
// Copyright (c) 2021 the ethier authors (github.com/divergencetech/ethier)

pragma solidity >=0.8.0;

/// @title DynamicBuffer
/// @author David Huber (@cxkoda) and Simon Fremaux (@dievardump). See also
///         https://raw.githubusercontent.com/dievardump/solidity-dynamic-buffer
/// @notice This library is used to allocate a big amount of container memory
//          which will be subsequently filled without needing to reallocate
///         memory.
/// @dev First, allocate memory.
///      Then use `buffer.appendUnchecked(theBytes)` or `appendSafe()` if
///      bounds checking is required.
library DynamicBuffer {
    /// @notice Allocates container space for the DynamicBuffer
    /// @param capacity_ The intended max amount of bytes in the buffer
    /// @return buffer The memory location of the buffer
    /// @dev Allocates `capacity_ + 0x60` bytes of space
    ///      The buffer array starts at the first container data position,
    ///      (i.e. `buffer = container + 0x20`)
    function allocate(uint256 capacity_)
        internal
        pure
        returns (bytes memory buffer)
    {
        assembly {
            // Get next-free memory address
            let container := mload(0x40)

            // Allocate memory by setting a new next-free address
            {
                // Add 2 x 32 bytes in size for the two length fields
                // Add 32 bytes safety space for 32B chunked copy
                let size := add(capacity_, 0x60)
                let newNextFree := add(container, size)
                mstore(0x40, newNextFree)
            }

            // Set the correct container length
            {
                let length := add(capacity_, 0x40)
                mstore(container, length)
            }

            // The buffer starts at idx 1 in the container (0 is length)
            buffer := add(container, 0x20)

            // Init content with length 0
            mstore(buffer, 0)
        }

        return buffer;
    }

    /// @notice Appends data to buffer, and update buffer length
    /// @param buffer the buffer to append the data to
    /// @param data the data to append
    /// @dev Does not perform out-of-bound checks (container capacity)
    ///      for efficiency.
    function appendUnchecked(bytes memory buffer, bytes memory data)
        internal
        pure
    {
        assembly {
            let length := mload(data)
            for {
                data := add(data, 0x20)
                let dataEnd := add(data, length)
                let copyTo := add(buffer, add(mload(buffer), 0x20))
            } lt(data, dataEnd) {
                data := add(data, 0x20)
                copyTo := add(copyTo, 0x20)
            } {
                // Copy 32B chunks from data to buffer.
                // This may read over data array boundaries and copy invalid
                // bytes, which doesn't matter in the end since we will
                // later set the correct buffer length, and have allocated an
                // additional word to avoid buffer overflow.
                mstore(copyTo, mload(data))
            }

            // Update buffer length
            mstore(buffer, add(mload(buffer), length))
        }
    }

    /// @notice Appends data to buffer, and update buffer length
    /// @param buffer the buffer to append the data to
    /// @param data the data to append
    /// @dev Performs out-of-bound checks and calls `appendUnchecked`.
    function appendSafe(bytes memory buffer, bytes memory data) internal pure {
        checkOverflow(buffer, data.length);
        appendUnchecked(buffer, data);
    }

    /// @notice Appends data encoded as Base64 to buffer.
    /// @param fileSafe  Whether to replace '+' with '-' and '/' with '_'.
    /// @param noPadding Whether to strip away the padding.
    /// @dev Encodes `data` using the base64 encoding described in RFC 4648.
    /// See: https://datatracker.ietf.org/doc/html/rfc4648
    /// Author: Modified from Solady (https://github.com/vectorized/solady/blob/main/src/utils/Base64.sol)
    /// Author: Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/Base64.sol)
    /// Author: Modified from (https://github.com/Brechtpd/base64/blob/main/base64.sol) by Brecht Devos.
    function appendSafeBase64(
        bytes memory buffer,
        bytes memory data,
        bool fileSafe,
        bool noPadding
    ) internal pure {
        uint256 dataLength = data.length;

        if (data.length == 0) {
            return;
        }

        uint256 encodedLength;
        uint256 r;
        assembly {
            // For each 3 bytes block, we will have 4 bytes in the base64
            // encoding: `encodedLength = 4 * divCeil(dataLength, 3)`.
            // The `shl(2, ...)` is equivalent to multiplying by 4.
            encodedLength := shl(2, div(add(dataLength, 2), 3))

            r := mod(dataLength, 3)
            if noPadding {
                // if r == 0 => no modification
                // if r == 1 => encodedLength -= 2
                // if r == 2 => encodedLength -= 1
                encodedLength := sub(
                    encodedLength,
                    add(iszero(iszero(r)), eq(r, 1))
                )
            }
        }

        checkOverflow(buffer, encodedLength);

        assembly {
            let nextFree := mload(0x40)

            // Store the table into the scratch space.
            // Offsetted by -1 byte so that the `mload` will load the character.
            // We will rewrite the free memory pointer at `0x40` later with
            // the allocated size.
            mstore(0x1f, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef")
            mstore(
                0x3f,
                sub(
                    "ghijklmnopqrstuvwxyz0123456789-_",
                    // The magic constant 0x0230 will translate "-_" + "+/".
                    mul(iszero(fileSafe), 0x0230)
                )
            )

            // Skip the first slot, which stores the length.
            let ptr := add(add(buffer, 0x20), mload(buffer))
            let end := add(data, dataLength)

            // Run over the input, 3 bytes at a time.
            // prettier-ignore
            // solhint-disable-next-line no-empty-blocks
            for {} 1 {} {
                    data := add(data, 3) // Advance 3 bytes.
                    let input := mload(data)

                    // Write 4 bytes. Optimized for fewer stack operations.
                    mstore8(    ptr    , mload(and(shr(18, input), 0x3F)))
                    mstore8(add(ptr, 1), mload(and(shr(12, input), 0x3F)))
                    mstore8(add(ptr, 2), mload(and(shr( 6, input), 0x3F)))
                    mstore8(add(ptr, 3), mload(and(        input , 0x3F)))
                    
                    ptr := add(ptr, 4) // Advance 4 bytes.
                    // prettier-ignore
                    if iszero(lt(data, end)) { break }
                }

            if iszero(noPadding) {
                // Offset `ptr` and pad with '='. We can simply write over the end.
                mstore8(sub(ptr, iszero(iszero(r))), 0x3d) // Pad at `ptr - 1` if `r > 0`.
                mstore8(sub(ptr, shl(1, eq(r, 1))), 0x3d) // Pad at `ptr - 2` if `r == 1`.
            }

            mstore(buffer, add(mload(buffer), encodedLength))
            mstore(0x40, nextFree)
        }
    }

    /// @notice Appends data encoded as Base64 to buffer.
    /// @param fileSafe  Whether to replace '+' with '-' and '/' with '_'.
    /// @param noPadding Whether to strip away the padding.
    /// @dev Encodes `data` using the base64 encoding described in RFC 4648.
    /// See: https://datatracker.ietf.org/doc/html/rfc4648
    /// Author: Modified from Solady (https://github.com/vectorized/solady/blob/main/src/utils/Base64.sol)
    /// Author: Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/Base64.sol)
    /// Author: Modified from (https://github.com/Brechtpd/base64/blob/main/base64.sol) by Brecht Devos.
    function appendUncheckedBase64(
        bytes memory buffer,
        bytes memory data,
        bool fileSafe,
        bool noPadding
    ) internal pure {
        uint256 dataLength = data.length;

        if (data.length == 0) {
            return;
        }

        uint256 encodedLength;
        uint256 r;
        assembly {
            // For each 3 bytes block, we will have 4 bytes in the base64
            // encoding: `encodedLength = 4 * divCeil(dataLength, 3)`.
            // The `shl(2, ...)` is equivalent to multiplying by 4.
            encodedLength := shl(2, div(add(dataLength, 2), 3))

            r := mod(dataLength, 3)
            if noPadding {
                // if r == 0 => no modification
                // if r == 1 => encodedLength -= 2
                // if r == 2 => encodedLength -= 1
                encodedLength := sub(
                    encodedLength,
                    add(iszero(iszero(r)), eq(r, 1))
                )
            }
        }

        assembly {
            let nextFree := mload(0x40)

            // Store the table into the scratch space.
            // Offsetted by -1 byte so that the `mload` will load the character.
            // We will rewrite the free memory pointer at `0x40` later with
            // the allocated size.
            mstore(0x1f, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef")
            mstore(
                0x3f,
                sub(
                    "ghijklmnopqrstuvwxyz0123456789-_",
                    // The magic constant 0x0230 will translate "-_" + "+/".
                    mul(iszero(fileSafe), 0x0230)
                )
            )

            // Skip the first slot, which stores the length.
            let ptr := add(add(buffer, 0x20), mload(buffer))
            let end := add(data, dataLength)

            // Run over the input, 3 bytes at a time.
            // prettier-ignore
            // solhint-disable-next-line no-empty-blocks
            for {} 1 {} {
                    data := add(data, 3) // Advance 3 bytes.
                    let input := mload(data)

                    // Write 4 bytes. Optimized for fewer stack operations.
                    mstore8(    ptr    , mload(and(shr(18, input), 0x3F)))
                    mstore8(add(ptr, 1), mload(and(shr(12, input), 0x3F)))
                    mstore8(add(ptr, 2), mload(and(shr( 6, input), 0x3F)))
                    mstore8(add(ptr, 3), mload(and(        input , 0x3F)))
                    
                    ptr := add(ptr, 4) // Advance 4 bytes.
                    // prettier-ignore
                    if iszero(lt(data, end)) { break }
                }

            if iszero(noPadding) {
                // Offset `ptr` and pad with '='. We can simply write over the end.
                mstore8(sub(ptr, iszero(iszero(r))), 0x3d) // Pad at `ptr - 1` if `r > 0`.
                mstore8(sub(ptr, shl(1, eq(r, 1))), 0x3d) // Pad at `ptr - 2` if `r == 1`.
            }

            mstore(buffer, add(mload(buffer), encodedLength))
            mstore(0x40, nextFree)
        }
    }

    /// @notice Returns the capacity of a given buffer.
    function capacity(bytes memory buffer) internal pure returns (uint256) {
        uint256 cap;
        assembly {
            cap := sub(mload(sub(buffer, 0x20)), 0x40)
        }
        return cap;
    }

    /// @notice Reverts if the buffer will overflow after appending a given
    /// number of bytes.
    function checkOverflow(bytes memory buffer, uint256 addedLength)
        internal
        pure
    {
        uint256 cap = capacity(buffer);
        uint256 newLength = buffer.length + addedLength;
        if (cap < newLength) {
            revert("DynamicBuffer: Appending out of bounds.");
        }
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 500
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"name":"InvalidRequestsLength","type":"error"},{"inputs":[],"name":"HTML_BASE64_DATA_URI_BYTES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HTML_BODY_CLOSED_RAW","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HTML_BODY_CLOSED_URL_SAFE","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HTML_BODY_OPEN_RAW","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HTML_BODY_OPEN_URL_SAFE","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HTML_TAG_RAW","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HTML_TAG_URL_SAFE","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SCRIPT_INLINE_BYTES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"URLS_RAW_BYTES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"URLS_SAFE_BYTES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"contractData","type":"bytes"},{"internalType":"bytes","name":"scriptContent","type":"bytes"}],"internalType":"struct InlineScriptRequest[]","name":"requests","type":"tuple[]"}],"name":"getBufferSizeForEncodedHTMLInline","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"contractData","type":"bytes"},{"internalType":"uint8","name":"wrapType","type":"uint8"},{"internalType":"bytes","name":"wrapPrefix","type":"bytes"},{"internalType":"bytes","name":"wrapSuffix","type":"bytes"},{"internalType":"bytes","name":"scriptContent","type":"bytes"}],"internalType":"struct WrappedScriptRequest[]","name":"requests","type":"tuple[]"}],"name":"getBufferSizeForEncodedHTMLWrapped","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"contractData","type":"bytes"},{"internalType":"bytes","name":"scriptContent","type":"bytes"}],"internalType":"struct InlineScriptRequest[]","name":"requests","type":"tuple[]"}],"name":"getBufferSizeForHTMLInline","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"contractData","type":"bytes"},{"internalType":"uint8","name":"wrapType","type":"uint8"},{"internalType":"bytes","name":"wrapPrefix","type":"bytes"},{"internalType":"bytes","name":"wrapSuffix","type":"bytes"},{"internalType":"bytes","name":"scriptContent","type":"bytes"}],"internalType":"struct WrappedScriptRequest[]","name":"requests","type":"tuple[]"}],"name":"getBufferSizeForHTMLWrapped","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"contractData","type":"bytes"},{"internalType":"uint8","name":"wrapType","type":"uint8"},{"internalType":"bytes","name":"wrapPrefix","type":"bytes"},{"internalType":"bytes","name":"wrapSuffix","type":"bytes"},{"internalType":"bytes","name":"scriptContent","type":"bytes"}],"internalType":"struct WrappedScriptRequest[]","name":"requests","type":"tuple[]"}],"name":"getBufferSizeForURLSafeHTMLWrapped","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"contractData","type":"bytes"},{"internalType":"bytes","name":"scriptContent","type":"bytes"}],"internalType":"struct InlineScriptRequest[]","name":"requests","type":"tuple[]"},{"internalType":"uint256","name":"bufferSize","type":"uint256"}],"name":"getEncodedHTMLInline","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"contractData","type":"bytes"},{"internalType":"bytes","name":"scriptContent","type":"bytes"}],"internalType":"struct InlineScriptRequest[]","name":"requests","type":"tuple[]"},{"internalType":"uint256","name":"bufferSize","type":"uint256"}],"name":"getEncodedHTMLInlineString","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"contractData","type":"bytes"},{"internalType":"uint8","name":"wrapType","type":"uint8"},{"internalType":"bytes","name":"wrapPrefix","type":"bytes"},{"internalType":"bytes","name":"wrapSuffix","type":"bytes"},{"internalType":"bytes","name":"scriptContent","type":"bytes"}],"internalType":"struct WrappedScriptRequest[]","name":"requests","type":"tuple[]"},{"internalType":"uint256","name":"bufferSize","type":"uint256"}],"name":"getEncodedHTMLWrapped","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"contractData","type":"bytes"},{"internalType":"uint8","name":"wrapType","type":"uint8"},{"internalType":"bytes","name":"wrapPrefix","type":"bytes"},{"internalType":"bytes","name":"wrapSuffix","type":"bytes"},{"internalType":"bytes","name":"scriptContent","type":"bytes"}],"internalType":"struct WrappedScriptRequest[]","name":"requests","type":"tuple[]"},{"internalType":"uint256","name":"bufferSize","type":"uint256"}],"name":"getEncodedHTMLWrappedString","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"contractData","type":"bytes"},{"internalType":"bytes","name":"scriptContent","type":"bytes"}],"internalType":"struct InlineScriptRequest[]","name":"requests","type":"tuple[]"},{"internalType":"uint256","name":"bufferSize","type":"uint256"}],"name":"getHTMLInline","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"contractData","type":"bytes"},{"internalType":"bytes","name":"scriptContent","type":"bytes"}],"internalType":"struct InlineScriptRequest[]","name":"requests","type":"tuple[]"},{"internalType":"uint256","name":"bufferSize","type":"uint256"}],"name":"getHTMLInlineString","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"contractData","type":"bytes"},{"internalType":"uint8","name":"wrapType","type":"uint8"},{"internalType":"bytes","name":"wrapPrefix","type":"bytes"},{"internalType":"bytes","name":"wrapSuffix","type":"bytes"},{"internalType":"bytes","name":"scriptContent","type":"bytes"}],"internalType":"struct WrappedScriptRequest[]","name":"requests","type":"tuple[]"},{"internalType":"uint256","name":"bufferSize","type":"uint256"}],"name":"getHTMLWrapped","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"contractData","type":"bytes"},{"internalType":"uint8","name":"wrapType","type":"uint8"},{"internalType":"bytes","name":"wrapPrefix","type":"bytes"},{"internalType":"bytes","name":"wrapSuffix","type":"bytes"},{"internalType":"bytes","name":"scriptContent","type":"bytes"}],"internalType":"struct WrappedScriptRequest[]","name":"requests","type":"tuple[]"},{"internalType":"uint256","name":"bufferSize","type":"uint256"}],"name":"getHTMLWrappedString","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"contractData","type":"bytes"},{"internalType":"uint8","name":"wrapType","type":"uint8"},{"internalType":"bytes","name":"wrapPrefix","type":"bytes"},{"internalType":"bytes","name":"wrapSuffix","type":"bytes"},{"internalType":"bytes","name":"scriptContent","type":"bytes"}],"internalType":"struct WrappedScriptRequest[]","name":"requests","type":"tuple[]"},{"internalType":"uint256","name":"bufferSize","type":"uint256"}],"name":"getHTMLWrappedURLSafe","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"contractData","type":"bytes"},{"internalType":"bytes","name":"scriptContent","type":"bytes"}],"internalType":"struct InlineScriptRequest","name":"request","type":"tuple"}],"name":"getInlineScriptSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"contractData","type":"bytes"},{"internalType":"uint8","name":"wrapType","type":"uint8"},{"internalType":"bytes","name":"wrapPrefix","type":"bytes"},{"internalType":"bytes","name":"wrapSuffix","type":"bytes"},{"internalType":"bytes","name":"scriptContent","type":"bytes"}],"internalType":"struct WrappedScriptRequest[]","name":"requests","type":"tuple[]"},{"internalType":"uint256","name":"bufferSize","type":"uint256"}],"name":"getURLSafeHTMLWrappedString","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"contractData","type":"bytes"},{"internalType":"uint8","name":"wrapType","type":"uint8"},{"internalType":"bytes","name":"wrapPrefix","type":"bytes"},{"internalType":"bytes","name":"wrapSuffix","type":"bytes"},{"internalType":"bytes","name":"scriptContent","type":"bytes"}],"internalType":"struct WrappedScriptRequest","name":"request","type":"tuple"}],"name":"getURLSafeWrappedScriptSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"contractData","type":"bytes"},{"internalType":"uint8","name":"wrapType","type":"uint8"},{"internalType":"bytes","name":"wrapPrefix","type":"bytes"},{"internalType":"bytes","name":"wrapSuffix","type":"bytes"},{"internalType":"bytes","name":"scriptContent","type":"bytes"}],"internalType":"struct WrappedScriptRequest","name":"request","type":"tuple"}],"name":"getWrappedScriptSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b50611ad2806100206000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80639e708330116100f9578063c03f39cd11610097578063cab6a3f311610071578063cab6a3f3146103db578063d602d7d0146103ee578063e572b8a01461042a578063f051dcf81461043257600080fd5b8063c03f39cd146103a2578063c71dd026146103b5578063c8d00e05146103c857600080fd5b8063b8108e30116100d3578063b8108e3014610361578063b97e52da14610374578063ba69524d14610387578063bee84ae31461039a57600080fd5b80639e70833014610307578063a0a5eeac1461033b578063b4f7d41e1461034e57600080fd5b8063668db168116101665780637603465f116101405780637603465f146102c65780637ea05006146102d957806387598e52146102ec5780639a7f08e0146102f457600080fd5b8063668db1681461029857806368e1644a146102ab5780637510ac24146102be57600080fd5b8063479751c3116101a2578063479751c31461024557806349a6b847146102585780634ce2f93114610260578063529df5d71461028557600080fd5b8063053f1eb0146101c957806333a656c11461021157806334c3c9d514610232575b600080fd5b6101fb6040518060400160405280601381526020017225323533432532353246626f6479253235334560681b81525081565b604051610208919061131f565b60405180910390f35b61022461021f366004611385565b61045f565b604051908152602001610208565b6101fb6102403660046113c7565b6104e7565b6101fb6102533660046113c7565b61059b565b610224601181565b6101fb604051806040016040528060068152602001651e343a36b61f60d11b81525081565b6102246102933660046115dd565b6105aa565b6102246102a6366004611723565b6105cf565b6102246102b9366004611385565b61060f565b610224601681565b6101fb6102d43660046113c7565b6106aa565b6101fb6102e73660046113c7565b61086d565b610224602c81565b6101fb6103023660046113c7565b610882565b6101fb60405180604001604052806015815260200174646174612533417465787425324668746d6c25324360581b81525081565b610224610349366004611385565b61088f565b6101fb61035c3660046113c7565b6108b3565b61022461036f366004611723565b610a96565b610224610382366004611385565b610af3565b6101fb6103953660046113c7565b610b8e565b610224606081565b6101fb6103b03660046113c7565b610d67565b6101fb6103c33660046113c7565b610d74565b6101fb6103d63660046113c7565b610d81565b6102246103e9366004611385565b610d8e565b6101fb6040518060400160405280601881526020017f3c626f6479207374796c653d276d617267696e3a303b273e000000000000000081525081565b6101fb610d9b565b6101fb6040518060400160405280600e81526020016d1e17b137b23c9f1e17b43a36b61f60911b81525081565b6040805160808101825260608082526000602083018190529282018190528082015281908190849081156104d8575b8686848181106104a0576104a0611758565b90506020028101906104b2919061176e565b6104bb9061178e565b90506104c6816105aa565b8401935081836001019350831061048e575b505050603d0190505b92915050565b606060006104f68585856106aa565b9050600061051282516000600360028301046004029050919050565b6016019050600061053a82604080518281016060018252910181526000602090910190815290565b90506105846040518060400160405280601681526020017f646174613a746578742f68746d6c3b6261736536342c0000000000000000000081525082610db790919063ffffffff16565b6105918184600080610dd0565b9695505050505050565b606060006104f6858585610b8e565b60006105c88260000151836020015184604001518560600151610edd565b5192915050565b60008060006105dd84610f6a565b9150915060006105ff8560000151866020015187604001518860c00151610edd565b5191519251909201019392505050565b6040805160e08101825260608082526000602083018190529282018190528082018390526080820181905260a0820181905260c0820152819081908490811561069d575b86868481811061066557610665611758565b9050602002810190610677919061179a565b610680906117b0565b905061068b81610a96565b84019350818360010193508310610653575b5050506060019392505050565b60608260008190036106cf57604051632a553e1560e11b815260040160405180910390fd5b604080516060818601018252908401815260006020909101818152905061071d604051806040016040528060068152602001651e343a36b61f60d11b81525082610db790919063ffffffff16565b60408051808201909152601881527f3c626f6479207374796c653d276d617267696e3a303b273e0000000000000000602082015261075c908290610db7565b6060806107ab6040518060e001604052806060815260200160006001600160a01b0316815260200160608152602001600060ff1681526020016060815260200160608152602001606081525090565b60005b8989828181106107c0576107c0611758565b90506020028101906107d2919061179a565b6107db906117b0565b91506107e682610f6a565b90945092506107f58585610db7565b61081b6108148360000151846020015185604001518660c00151610edd565b8690610db7565b6108258584610db7565b6001018581106107ae5760408051808201909152600e81526d1e17b137b23c9f1e17b43a36b61f60911b602082015261085f908690610db7565b509298975050505050505050565b606061087a84848461059b565b949350505050565b606061087a848484610b8e565b60008061089c8484610af3565b905060046003600283010402601601949350505050565b60608260008190036108d857604051632a553e1560e11b815260040160405180910390fd5b604080516060818601018252908401815260006020909101818152905061093560405180604001604052806015815260200174646174612533417465787425324668746d6c25324360581b81525082610db790919063ffffffff16565b61095860405180606001604052806038815260200161189a603891398290610db7565b6060806109a76040518060e001604052806060815260200160006001600160a01b0316815260200160608152602001600060ff1681526020016060815260200160608152602001606081525090565b60005b8989828181106109bc576109bc611758565b90506020028101906109ce919061179a565b6109d7906117b0565b91506109e2826110d8565b90945092506109f18585610db7565b816060015160ff16600003610a2e57610a29610a1f8360000151846020015185604001518660c00151610edd565b8690600080610dd0565b610a4d565b610a4d6108148360000151846020015185604001518660c00151610edd565b610a578584610db7565b6001018581106109aa5760408051808201909152601381527225323533432532353246626f6479253235334560681b602082015261085f908690610db7565b6000806000610aa4846110d8565b915091506000610ac68560000151866020015187604001518860c00151610edd565b519050846060015160ff16600003610ae5576004600360028301040290505b905191519091010192915050565b6040805160e08101825260608082526000602083018190529282018190528082018390526080820181905260a0820181905260c08201528190819084908115610b81575b868684818110610b4957610b49611758565b9050602002810190610b5b919061179a565b610b64906117b0565b9050610b6f816105cf565b84019350818360010193508310610b37575b505050602c019392505050565b6060826000819003610bb357604051632a553e1560e11b815260040160405180910390fd5b6040805160608186010182529084018152600060209091018181529050610c01604051806040016040528060068152602001651e343a36b61f60d11b81525082610db790919063ffffffff16565b60408051808201909152601881527f3c626f6479207374796c653d276d617267696e3a303b273e00000000000000006020820152610c40908290610db7565b6040805180820190915260088152671e39b1b934b83a1f60c11b6020820152610c6a908290610db7565b610c9e60405180608001604052806060815260200160006001600160a01b0316815260200160608152602001606081525090565b60005b878782818110610cb357610cb3611758565b9050602002810190610cc5919061176e565b610cce9061178e565b9150610cf6610cef8360000151846020015185604001518660600151610edd565b8490610db7565b600101838110610ca1576040805180820190915260098152681e17b9b1b934b83a1f60b91b6020820152610d2b908490610db7565b60408051808201909152600e81526d1e17b137b23c9f1e17b43a36b61f60911b6020820152610d5b908490610db7565b50909695505050505050565b606061087a8484846104e7565b606061087a8484846108b3565b606061087a8484846106aa565b60008061089c848461045f565b60405180606001604052806038815260200161189a6038913981565b610dc2828251611210565b610dcc8282611299565b5050565b82516000819003610de15750610ed7565b60036002828101829004901b9082068315610e03576001811481151501820391505b610e0d8783611210565b6040517f4142434445464748494a4b4c4d4e4f505152535455565758595a616263646566601f526102308615027f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5f03603f52875160208901018488015b6003890198508851603f8160121c16518353603f81600c1c16516001840153603f8160061c16516002840153603f811651600384015350600482019150808910610e6a575085610ec957603d831515820353603d6001841460011b8203535b508751909201875250604052505b50505050565b805160609015610eee57508061087a565b604051633e58d56560e21b81526001600160a01b0385169063f963559490610f1c90889087906004016117bc565b600060405180830381865afa158015610f39573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f6191908101906117e1565b95945050505050565b606080826060015160ff16600003610fc857604051806040016040528060088152602001671e39b1b934b83a1f60c11b815250604051806040016040528060098152602001681e17b9b1b934b83a1f60b91b81525091509150915091565b826060015160ff1660010361101d57604051806060016040528060298152602001611871602991396040518060400160405280600b81526020016a111f1e17b9b1b934b83a1f60a91b81525091509150915091565b826060015160ff166002036110725760405180608001604052806045815260200161191b604591396040518060400160405280600b81526020016a111f1e17b9b1b934b83a1f60a91b81525091509150915091565b826060015160ff166003036110c757604051806080016040528060448152602001611a59604491396040518060400160405280600b81526020016a111f1e17b9b1b934b83a1f60a91b81525091509150915091565b5050608081015160a0909101519091565b6060806001836060015160ff1611611142576040518060800160405280604981526020016118d2604991396040518060400160405280601f81526020017f253235323225323533452532353343253235324673637269707425323533450081525091509150915091565b826060015160ff166002036111a9576040518060a00160405280607d8152602001611960607d91396040518060400160405280601f81526020017f253235323225323533452532353343253235324673637269707425323533450081525091509150915091565b826060015160ff166003036110c7576040518060a00160405280607c81526020016119dd607c91396040518060400160405280601f81526020017f253235323225323533452532353343253235324673637269707425323533450081525091509150915091565b600061122283601f190151603f190190565b90506000828451611233919061184f565b905080821015610ed75760405162461bcd60e51b815260206004820152602760248201527f44796e616d69634275666665723a20417070656e64696e67206f7574206f66206044820152663137bab732399760c91b606482015260840160405180910390fd5b8051602082019150808201602084510184015b818410156112c45783518152602093840193016112ac565b505082510190915250565b60005b838110156112ea5781810151838201526020016112d2565b50506000910152565b6000815180845261130b8160208601602086016112cf565b601f01601f19169290920160200192915050565b60208152600061133260208301846112f3565b9392505050565b60008083601f84011261134b57600080fd5b50813567ffffffffffffffff81111561136357600080fd5b6020830191508360208260051b850101111561137e57600080fd5b9250929050565b6000806020838503121561139857600080fd5b823567ffffffffffffffff8111156113af57600080fd5b6113bb85828601611339565b90969095509350505050565b6000806000604084860312156113dc57600080fd5b833567ffffffffffffffff8111156113f357600080fd5b6113ff86828701611339565b909790965060209590950135949350505050565b634e487b7160e01b600052604160045260246000fd5b60405160e0810167ffffffffffffffff8111828210171561144c5761144c611413565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561147b5761147b611413565b604052919050565b600067ffffffffffffffff82111561149d5761149d611413565b50601f01601f191660200190565b600082601f8301126114bc57600080fd5b81356114cf6114ca82611483565b611452565b8181528460208386010111156114e457600080fd5b816020850160208301376000918101602001919091529392505050565b80356001600160a01b038116811461151857600080fd5b919050565b60006080828403121561152f57600080fd5b6040516080810167ffffffffffffffff828210818311171561155357611553611413565b81604052829350843591508082111561156b57600080fd5b611577868387016114ab565b835261158560208601611501565b6020840152604085013591508082111561159e57600080fd5b6115aa868387016114ab565b604084015260608501359150808211156115c357600080fd5b506115d0858286016114ab565b6060830152505092915050565b6000602082840312156115ef57600080fd5b813567ffffffffffffffff81111561160657600080fd5b61087a8482850161151d565b803560ff8116811461151857600080fd5b600060e0828403121561163557600080fd5b61163d611429565b9050813567ffffffffffffffff8082111561165757600080fd5b611663858386016114ab565b835261167160208501611501565b6020840152604084013591508082111561168a57600080fd5b611696858386016114ab565b60408401526116a760608501611612565b606084015260808401359150808211156116c057600080fd5b6116cc858386016114ab565b608084015260a08401359150808211156116e557600080fd5b6116f1858386016114ab565b60a084015260c084013591508082111561170a57600080fd5b50611717848285016114ab565b60c08301525092915050565b60006020828403121561173557600080fd5b813567ffffffffffffffff81111561174c57600080fd5b61087a84828501611623565b634e487b7160e01b600052603260045260246000fd5b60008235607e1983360301811261178457600080fd5b9190910192915050565b60006104e1368361151d565b6000823560de1983360301811261178457600080fd5b60006104e13683611623565b6040815260006117cf60408301856112f3565b8281036020840152610f6181856112f3565b6000602082840312156117f357600080fd5b815167ffffffffffffffff81111561180a57600080fd5b8201601f8101841361181b57600080fd5b80516118296114ca82611483565b81815285602083850101111561183e57600080fd5b610f618260208301602086016112cf565b808201808211156104e157634e487b7160e01b600052601160045260246000fdfe3c736372697074207372633d22646174613a746578742f6a6176617363726970743b6261736536342c2532353343626f647925323532307374796c65253235334425323532376d617267696e25323533413025323533422532353237253235334525323533437363726970742532353230737263253235334425323532326461746125323533417465787425323532466a617661736372697074253235334262617365363425323532433c73637269707420747970653d22746578742f6a6176617363726970742b677a697022207372633d22646174613a746578742f6a6176617363726970743b6261736536342c2532353343736372697074253235323074797065253235334425323532327465787425323532466a6176617363726970742532353242677a697025323532322532353230737263253235334425323532326461746125323533417465787425323532466a617661736372697074253235334262617365363425323532432532353343736372697074253235323074797065253235334425323532327465787425323532466a6176617363726970742532353242706e6725323532322532353230737263253235334425323532326461746125323533417465787425323532466a617661736372697074253235334262617365363425323532433c73637269707420747970653d22746578742f6a6176617363726970742b706e6722207372633d22646174613a746578742f6a6176617363726970743b6261736536342ca2646970667358221220f200975632833d7b7eb6dd9a7b1ae14a0e2ab14fbacb924824ef01ebe45fadf964736f6c63430008110033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101c45760003560e01c80639e708330116100f9578063c03f39cd11610097578063cab6a3f311610071578063cab6a3f3146103db578063d602d7d0146103ee578063e572b8a01461042a578063f051dcf81461043257600080fd5b8063c03f39cd146103a2578063c71dd026146103b5578063c8d00e05146103c857600080fd5b8063b8108e30116100d3578063b8108e3014610361578063b97e52da14610374578063ba69524d14610387578063bee84ae31461039a57600080fd5b80639e70833014610307578063a0a5eeac1461033b578063b4f7d41e1461034e57600080fd5b8063668db168116101665780637603465f116101405780637603465f146102c65780637ea05006146102d957806387598e52146102ec5780639a7f08e0146102f457600080fd5b8063668db1681461029857806368e1644a146102ab5780637510ac24146102be57600080fd5b8063479751c3116101a2578063479751c31461024557806349a6b847146102585780634ce2f93114610260578063529df5d71461028557600080fd5b8063053f1eb0146101c957806333a656c11461021157806334c3c9d514610232575b600080fd5b6101fb6040518060400160405280601381526020017225323533432532353246626f6479253235334560681b81525081565b604051610208919061131f565b60405180910390f35b61022461021f366004611385565b61045f565b604051908152602001610208565b6101fb6102403660046113c7565b6104e7565b6101fb6102533660046113c7565b61059b565b610224601181565b6101fb604051806040016040528060068152602001651e343a36b61f60d11b81525081565b6102246102933660046115dd565b6105aa565b6102246102a6366004611723565b6105cf565b6102246102b9366004611385565b61060f565b610224601681565b6101fb6102d43660046113c7565b6106aa565b6101fb6102e73660046113c7565b61086d565b610224602c81565b6101fb6103023660046113c7565b610882565b6101fb60405180604001604052806015815260200174646174612533417465787425324668746d6c25324360581b81525081565b610224610349366004611385565b61088f565b6101fb61035c3660046113c7565b6108b3565b61022461036f366004611723565b610a96565b610224610382366004611385565b610af3565b6101fb6103953660046113c7565b610b8e565b610224606081565b6101fb6103b03660046113c7565b610d67565b6101fb6103c33660046113c7565b610d74565b6101fb6103d63660046113c7565b610d81565b6102246103e9366004611385565b610d8e565b6101fb6040518060400160405280601881526020017f3c626f6479207374796c653d276d617267696e3a303b273e000000000000000081525081565b6101fb610d9b565b6101fb6040518060400160405280600e81526020016d1e17b137b23c9f1e17b43a36b61f60911b81525081565b6040805160808101825260608082526000602083018190529282018190528082015281908190849081156104d8575b8686848181106104a0576104a0611758565b90506020028101906104b2919061176e565b6104bb9061178e565b90506104c6816105aa565b8401935081836001019350831061048e575b505050603d0190505b92915050565b606060006104f68585856106aa565b9050600061051282516000600360028301046004029050919050565b6016019050600061053a82604080518281016060018252910181526000602090910190815290565b90506105846040518060400160405280601681526020017f646174613a746578742f68746d6c3b6261736536342c0000000000000000000081525082610db790919063ffffffff16565b6105918184600080610dd0565b9695505050505050565b606060006104f6858585610b8e565b60006105c88260000151836020015184604001518560600151610edd565b5192915050565b60008060006105dd84610f6a565b9150915060006105ff8560000151866020015187604001518860c00151610edd565b5191519251909201019392505050565b6040805160e08101825260608082526000602083018190529282018190528082018390526080820181905260a0820181905260c0820152819081908490811561069d575b86868481811061066557610665611758565b9050602002810190610677919061179a565b610680906117b0565b905061068b81610a96565b84019350818360010193508310610653575b5050506060019392505050565b60608260008190036106cf57604051632a553e1560e11b815260040160405180910390fd5b604080516060818601018252908401815260006020909101818152905061071d604051806040016040528060068152602001651e343a36b61f60d11b81525082610db790919063ffffffff16565b60408051808201909152601881527f3c626f6479207374796c653d276d617267696e3a303b273e0000000000000000602082015261075c908290610db7565b6060806107ab6040518060e001604052806060815260200160006001600160a01b0316815260200160608152602001600060ff1681526020016060815260200160608152602001606081525090565b60005b8989828181106107c0576107c0611758565b90506020028101906107d2919061179a565b6107db906117b0565b91506107e682610f6a565b90945092506107f58585610db7565b61081b6108148360000151846020015185604001518660c00151610edd565b8690610db7565b6108258584610db7565b6001018581106107ae5760408051808201909152600e81526d1e17b137b23c9f1e17b43a36b61f60911b602082015261085f908690610db7565b509298975050505050505050565b606061087a84848461059b565b949350505050565b606061087a848484610b8e565b60008061089c8484610af3565b905060046003600283010402601601949350505050565b60608260008190036108d857604051632a553e1560e11b815260040160405180910390fd5b604080516060818601018252908401815260006020909101818152905061093560405180604001604052806015815260200174646174612533417465787425324668746d6c25324360581b81525082610db790919063ffffffff16565b61095860405180606001604052806038815260200161189a603891398290610db7565b6060806109a76040518060e001604052806060815260200160006001600160a01b0316815260200160608152602001600060ff1681526020016060815260200160608152602001606081525090565b60005b8989828181106109bc576109bc611758565b90506020028101906109ce919061179a565b6109d7906117b0565b91506109e2826110d8565b90945092506109f18585610db7565b816060015160ff16600003610a2e57610a29610a1f8360000151846020015185604001518660c00151610edd565b8690600080610dd0565b610a4d565b610a4d6108148360000151846020015185604001518660c00151610edd565b610a578584610db7565b6001018581106109aa5760408051808201909152601381527225323533432532353246626f6479253235334560681b602082015261085f908690610db7565b6000806000610aa4846110d8565b915091506000610ac68560000151866020015187604001518860c00151610edd565b519050846060015160ff16600003610ae5576004600360028301040290505b905191519091010192915050565b6040805160e08101825260608082526000602083018190529282018190528082018390526080820181905260a0820181905260c08201528190819084908115610b81575b868684818110610b4957610b49611758565b9050602002810190610b5b919061179a565b610b64906117b0565b9050610b6f816105cf565b84019350818360010193508310610b37575b505050602c019392505050565b6060826000819003610bb357604051632a553e1560e11b815260040160405180910390fd5b6040805160608186010182529084018152600060209091018181529050610c01604051806040016040528060068152602001651e343a36b61f60d11b81525082610db790919063ffffffff16565b60408051808201909152601881527f3c626f6479207374796c653d276d617267696e3a303b273e00000000000000006020820152610c40908290610db7565b6040805180820190915260088152671e39b1b934b83a1f60c11b6020820152610c6a908290610db7565b610c9e60405180608001604052806060815260200160006001600160a01b0316815260200160608152602001606081525090565b60005b878782818110610cb357610cb3611758565b9050602002810190610cc5919061176e565b610cce9061178e565b9150610cf6610cef8360000151846020015185604001518660600151610edd565b8490610db7565b600101838110610ca1576040805180820190915260098152681e17b9b1b934b83a1f60b91b6020820152610d2b908490610db7565b60408051808201909152600e81526d1e17b137b23c9f1e17b43a36b61f60911b6020820152610d5b908490610db7565b50909695505050505050565b606061087a8484846104e7565b606061087a8484846108b3565b606061087a8484846106aa565b60008061089c848461045f565b60405180606001604052806038815260200161189a6038913981565b610dc2828251611210565b610dcc8282611299565b5050565b82516000819003610de15750610ed7565b60036002828101829004901b9082068315610e03576001811481151501820391505b610e0d8783611210565b6040517f4142434445464748494a4b4c4d4e4f505152535455565758595a616263646566601f526102308615027f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5f03603f52875160208901018488015b6003890198508851603f8160121c16518353603f81600c1c16516001840153603f8160061c16516002840153603f811651600384015350600482019150808910610e6a575085610ec957603d831515820353603d6001841460011b8203535b508751909201875250604052505b50505050565b805160609015610eee57508061087a565b604051633e58d56560e21b81526001600160a01b0385169063f963559490610f1c90889087906004016117bc565b600060405180830381865afa158015610f39573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f6191908101906117e1565b95945050505050565b606080826060015160ff16600003610fc857604051806040016040528060088152602001671e39b1b934b83a1f60c11b815250604051806040016040528060098152602001681e17b9b1b934b83a1f60b91b81525091509150915091565b826060015160ff1660010361101d57604051806060016040528060298152602001611871602991396040518060400160405280600b81526020016a111f1e17b9b1b934b83a1f60a91b81525091509150915091565b826060015160ff166002036110725760405180608001604052806045815260200161191b604591396040518060400160405280600b81526020016a111f1e17b9b1b934b83a1f60a91b81525091509150915091565b826060015160ff166003036110c757604051806080016040528060448152602001611a59604491396040518060400160405280600b81526020016a111f1e17b9b1b934b83a1f60a91b81525091509150915091565b5050608081015160a0909101519091565b6060806001836060015160ff1611611142576040518060800160405280604981526020016118d2604991396040518060400160405280601f81526020017f253235323225323533452532353343253235324673637269707425323533450081525091509150915091565b826060015160ff166002036111a9576040518060a00160405280607d8152602001611960607d91396040518060400160405280601f81526020017f253235323225323533452532353343253235324673637269707425323533450081525091509150915091565b826060015160ff166003036110c7576040518060a00160405280607c81526020016119dd607c91396040518060400160405280601f81526020017f253235323225323533452532353343253235324673637269707425323533450081525091509150915091565b600061122283601f190151603f190190565b90506000828451611233919061184f565b905080821015610ed75760405162461bcd60e51b815260206004820152602760248201527f44796e616d69634275666665723a20417070656e64696e67206f7574206f66206044820152663137bab732399760c91b606482015260840160405180910390fd5b8051602082019150808201602084510184015b818410156112c45783518152602093840193016112ac565b505082510190915250565b60005b838110156112ea5781810151838201526020016112d2565b50506000910152565b6000815180845261130b8160208601602086016112cf565b601f01601f19169290920160200192915050565b60208152600061133260208301846112f3565b9392505050565b60008083601f84011261134b57600080fd5b50813567ffffffffffffffff81111561136357600080fd5b6020830191508360208260051b850101111561137e57600080fd5b9250929050565b6000806020838503121561139857600080fd5b823567ffffffffffffffff8111156113af57600080fd5b6113bb85828601611339565b90969095509350505050565b6000806000604084860312156113dc57600080fd5b833567ffffffffffffffff8111156113f357600080fd5b6113ff86828701611339565b909790965060209590950135949350505050565b634e487b7160e01b600052604160045260246000fd5b60405160e0810167ffffffffffffffff8111828210171561144c5761144c611413565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561147b5761147b611413565b604052919050565b600067ffffffffffffffff82111561149d5761149d611413565b50601f01601f191660200190565b600082601f8301126114bc57600080fd5b81356114cf6114ca82611483565b611452565b8181528460208386010111156114e457600080fd5b816020850160208301376000918101602001919091529392505050565b80356001600160a01b038116811461151857600080fd5b919050565b60006080828403121561152f57600080fd5b6040516080810167ffffffffffffffff828210818311171561155357611553611413565b81604052829350843591508082111561156b57600080fd5b611577868387016114ab565b835261158560208601611501565b6020840152604085013591508082111561159e57600080fd5b6115aa868387016114ab565b604084015260608501359150808211156115c357600080fd5b506115d0858286016114ab565b6060830152505092915050565b6000602082840312156115ef57600080fd5b813567ffffffffffffffff81111561160657600080fd5b61087a8482850161151d565b803560ff8116811461151857600080fd5b600060e0828403121561163557600080fd5b61163d611429565b9050813567ffffffffffffffff8082111561165757600080fd5b611663858386016114ab565b835261167160208501611501565b6020840152604084013591508082111561168a57600080fd5b611696858386016114ab565b60408401526116a760608501611612565b606084015260808401359150808211156116c057600080fd5b6116cc858386016114ab565b608084015260a08401359150808211156116e557600080fd5b6116f1858386016114ab565b60a084015260c084013591508082111561170a57600080fd5b50611717848285016114ab565b60c08301525092915050565b60006020828403121561173557600080fd5b813567ffffffffffffffff81111561174c57600080fd5b61087a84828501611623565b634e487b7160e01b600052603260045260246000fd5b60008235607e1983360301811261178457600080fd5b9190910192915050565b60006104e1368361151d565b6000823560de1983360301811261178457600080fd5b60006104e13683611623565b6040815260006117cf60408301856112f3565b8281036020840152610f6181856112f3565b6000602082840312156117f357600080fd5b815167ffffffffffffffff81111561180a57600080fd5b8201601f8101841361181b57600080fd5b80516118296114ca82611483565b81815285602083850101111561183e57600080fd5b610f618260208301602086016112cf565b808201808211156104e157634e487b7160e01b600052601160045260246000fdfe3c736372697074207372633d22646174613a746578742f6a6176617363726970743b6261736536342c2532353343626f647925323532307374796c65253235334425323532376d617267696e25323533413025323533422532353237253235334525323533437363726970742532353230737263253235334425323532326461746125323533417465787425323532466a617661736372697074253235334262617365363425323532433c73637269707420747970653d22746578742f6a6176617363726970742b677a697022207372633d22646174613a746578742f6a6176617363726970743b6261736536342c2532353343736372697074253235323074797065253235334425323532327465787425323532466a6176617363726970742532353242677a697025323532322532353230737263253235334425323532326461746125323533417465787425323532466a617661736372697074253235334262617365363425323532432532353343736372697074253235323074797065253235334425323532327465787425323532466a6176617363726970742532353242706e6725323532322532353230737263253235334425323532326461746125323533417465787425323532466a617661736372697074253235334262617365363425323532433c73637269707420747970653d22746578742f6a6176617363726970742b706e6722207372633d22646174613a746578742f6a6176617363726970743b6261736536342ca2646970667358221220f200975632833d7b7eb6dd9a7b1ae14a0e2ab14fbacb924824ef01ebe45fadf964736f6c63430008110033

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

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.