creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "lib/ttg/src/PowerTokenDeployer.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\nimport { ContractHelper } from \"../lib/common/src/ContractHelper.sol\";\n\nimport { IDeployer, IPowerTokenDeployer } from \"./interfaces/IPowerTokenDeployer.sol\";\n\nimport { PowerToken } from \"./PowerToken.sol\";\n\n/**\n * @title  A Deterministic deployer of Power Token contracts using CREATE.\n * @author M^0 Labs\n */\ncontract PowerTokenDeployer is IPowerTokenDeployer {\n    /* ============ Variables ============ */\n\n    /// @inheritdoc IPowerTokenDeployer\n    address public immutable vault;\n\n    /// @inheritdoc IPowerTokenDeployer\n    address public immutable zeroGovernor;\n\n    /// @inheritdoc IDeployer\n    address public lastDeploy;\n\n    /// @inheritdoc IDeployer\n    uint256 public nonce;\n\n    /* ============ Constructor ============ */\n\n    /**\n     * @notice Constructs a new PowerTokenDeployer contract.\n     * @param  zeroGovernor_ The address of the ZeroGovernor contract.\n     * @param  vault_        The address of the Vault contract.\n     */\n    constructor(address zeroGovernor_, address vault_) {\n        if ((zeroGovernor = zeroGovernor_) == address(0)) revert InvalidZeroGovernorAddress();\n        if ((vault = vault_) == address(0)) revert InvalidVaultAddress();\n    }\n\n    /* ============ Interactive Functions ============ */\n\n    /// @inheritdoc IPowerTokenDeployer\n    function deploy(address bootstrapToken_, address standardGovernor_, address cashToken_) external returns (address) {\n        if (msg.sender != zeroGovernor) revert NotZeroGovernor();\n\n        unchecked {\n            ++nonce;\n        }\n\n        return lastDeploy = address(new PowerToken(bootstrapToken_, standardGovernor_, cashToken_, vault));\n    }\n\n    /// @inheritdoc IDeployer\n    function nextDeploy() external view returns (address) {\n        unchecked {\n            return ContractHelper.getContractFrom(address(this), nonce + 1);\n        }\n    }\n}\n"
      },
      "lib/ttg/lib/common/src/ContractHelper.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\n// solhint-disable max-line-length\n\n/**\n * @title  A helper contract to get the address of a contract deployed by an account with a given nonce.\n * @author M^0 Labs\n * @dev    See the following sources for very similar implementations:\n *           - https://github.com/foundry-rs/forge-std/blob/914702ae99c92fcc41db5128ae57d24a11be4a39/src/Script.sol\n *           - https://github.com/foundry-rs/forge-std/blob/578968243529db44acffcb802196ccab9b54db88/src/StdUtils.sol#L90\n *           - https://github.com/SoulWallet/soul-wallet-contract/blob/develop/script/DeployHelper.sol#L133\n *           - https://github.com/nomoixyz/vulcan/blob/f67740f8a9c846a543aebf29433ad69c3f0ff337/src/_internal/Accounts.sol#L118\n *           - https://github.com/chainlight-io/publications/blob/887d6fe1a4f53573de6b89dbecba0c91b091dba2/ctf-writeups/paradigm2023/dropper/Solve.s.sol#L29\n *           - https://github.com/HerodotusDev/herodotus-evm/blob/a0e9c8be1a17838633d3dcdd54b72682f7654abd/src/lib/CREATE.sol#L5\n *           - https://github.com/Polymarket/ctf-exchange/blob/2745c3017400dbc1925711005fe76b018b999155/src/dev/util/Predictor.sol#L9\n *           - https://github.com/delegatexyz/delegate-market/blob/2418182fe81491114370287412926b57c1ddbd94/script/ComputeAddress.s.sol#L5\n *         Note that this implementation, as do many others, assumes an account does not have a nonce greater than 0xffffffff.\n *         If this is not the case, the address of the contract deployed by the account with the given nonce will be incorrect.\n */\nlibrary ContractHelper {\n    /**\n     * @notice Returns the expected address of a contract deployed by `account_` with transaction count `nonce_`.\n     * @param  account_  The address of the account deploying a contract.\n     * @param  nonce_    The nonce used in the deployment transaction.\n     * @return contract_ The expected address of the deployed contract.\n     */\n    function getContractFrom(address account_, uint256 nonce_) internal pure returns (address contract_) {\n        return\n            address(\n                uint160(\n                    uint256(\n                        keccak256(\n                            nonce_ == 0x00\n                                ? abi.encodePacked(bytes1(0xd6), bytes1(0x94), account_, bytes1(0x80))\n                                : nonce_ <= 0x7f\n                                ? abi.encodePacked(bytes1(0xd6), bytes1(0x94), account_, uint8(nonce_))\n                                : nonce_ <= 0xff\n                                ? abi.encodePacked(bytes1(0xd7), bytes1(0x94), account_, bytes1(0x81), uint8(nonce_))\n                                : nonce_ <= 0xffff\n                                ? abi.encodePacked(bytes1(0xd8), bytes1(0x94), account_, bytes1(0x82), uint16(nonce_))\n                                : nonce_ <= 0xffffff\n                                ? abi.encodePacked(bytes1(0xd9), bytes1(0x94), account_, bytes1(0x83), uint24(nonce_))\n                                : abi.encodePacked(bytes1(0xda), bytes1(0x94), account_, bytes1(0x84), uint32(nonce_))\n                        )\n                    )\n                )\n            );\n    }\n}\n"
      },
      "lib/ttg/src/interfaces/IPowerTokenDeployer.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\nimport { IDeployer } from \"./IDeployer.sol\";\n\n/**\n * @title  A Deterministic deployer of Power Token contracts using CREATE.\n * @author M^0 Labs\n */\ninterface IPowerTokenDeployer is IDeployer {\n    /* ============ Custom Errors ============ */\n\n    /// @notice Revert message when the Vault specified in the constructor is address(0).\n    error InvalidVaultAddress();\n\n    /// @notice Revert message when the Zero Governor specified in the constructor is address(0).\n    error InvalidZeroGovernorAddress();\n\n    /// @notice Revert message when the caller is not the Zero Governor.\n    error NotZeroGovernor();\n\n    /* ============ Interactive Functions ============ */\n\n    /**\n     * @notice Deploys a new instance of a Power Token.\n     * @dev    Callable only by the Zero Governor.\n     * @param  bootstrapToken   The address of some token to bootstrap from.\n     * @param  standardGovernor The address of some Standard Governor.\n     * @param  cashToken        The address of some Cash Token.\n     * @return The address of the deployed Emergency Governor.\n     */\n    function deploy(address bootstrapToken, address standardGovernor, address cashToken) external returns (address);\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @notice Returns the address of the Vault.\n    function vault() external view returns (address);\n\n    /// @notice Returns the address of the Zero Governor.\n    function zeroGovernor() external view returns (address);\n}\n"
      },
      "lib/ttg/src/PowerToken.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\nimport { ERC20Helper } from \"../lib/erc20-helper/src/ERC20Helper.sol\";\nimport { UIntMath } from \"../lib/common/src/libs/UIntMath.sol\";\n\nimport { PureEpochs } from \"./libs/PureEpochs.sol\";\n\nimport { IEpochBasedVoteToken } from \"./abstract/interfaces/IEpochBasedVoteToken.sol\";\n\nimport { EpochBasedInflationaryVoteToken } from \"./abstract/EpochBasedInflationaryVoteToken.sol\";\n\nimport { IPowerToken } from \"./interfaces/IPowerToken.sol\";\n\n/*\n\n██████╗  ██████╗ ██╗    ██╗███████╗██████╗     ████████╗ ██████╗ ██╗  ██╗███████╗███╗   ██╗\n██╔══██╗██╔═══██╗██║    ██║██╔════╝██╔══██╗    ╚══██╔══╝██╔═══██╗██║ ██╔╝██╔════╝████╗  ██║\n██████╔╝██║   ██║██║ █╗ ██║█████╗  ██████╔╝       ██║   ██║   ██║█████╔╝ █████╗  ██╔██╗ ██║\n██╔═══╝ ██║   ██║██║███╗██║██╔══╝  ██╔══██╗       ██║   ██║   ██║██╔═██╗ ██╔══╝  ██║╚██╗██║\n██║     ╚██████╔╝╚███╔███╔╝███████╗██║  ██║       ██║   ╚██████╔╝██║  ██╗███████╗██║ ╚████║\n╚═╝      ╚═════╝  ╚══╝╚══╝ ╚══════╝╚═╝  ╚═╝       ╚═╝    ╚═════╝ ╚═╝  ╚═╝╚══════╝╚═╝  ╚═══╝\n\n-->> With great power comes great responsibility. <<--\n\n*/\n\n// NOTE: Balances and voting powers are bootstrapped from the bootstrap token, but delegations are not.\n// NOTE: Bootstrapping only works with a bootstrap token that supports the same PureEpochs as the clock mode.\n\n/**\n * @title  An instance of an EpochBasedInflationaryVoteToken delegating control to a Standard Governor,\n *         and enabling auctioning of the unowned inflated supply.\n * @author M^0 Labs\n */\ncontract PowerToken is IPowerToken, EpochBasedInflationaryVoteToken {\n    /* ============ Variables ============ */\n\n    /// @dev The number of auction periods in an epoch.\n    uint40 internal constant _AUCTION_PERIODS = 100;\n\n    /// @inheritdoc IPowerToken\n    uint240 public constant INITIAL_SUPPLY = 1_000_000;\n\n    /// @inheritdoc IPowerToken\n    address public immutable bootstrapToken;\n\n    /// @inheritdoc IPowerToken\n    address public immutable standardGovernor;\n\n    /// @inheritdoc IPowerToken\n    address public immutable vault;\n\n    /// @inheritdoc IPowerToken\n    uint16 public immutable bootstrapEpoch;\n\n    /// @dev The total supply of the bootstrap token at the bootstrap epoch.\n    uint240 internal immutable _bootstrapSupply;\n\n    /// @dev The starting epoch of the next cash token.\n    uint16 internal _nextCashTokenStartingEpoch;\n\n    /// @dev The address of the cash token required to buy from the token auction.\n    address internal _cashToken;\n\n    /// @dev The address of the next cash token.\n    address internal _nextCashToken;\n\n    /// @dev The starting epoch of the next target supply.\n    uint16 internal _nextTargetSupplyStartingEpoch;\n\n    /// @dev The current target supply of the token.\n    uint240 internal _targetSupply;\n\n    /// @dev The next target supply of the token.\n    uint240 internal _nextTargetSupply = INITIAL_SUPPLY;\n\n    /* ============ Modifiers ============ */\n\n    /// @dev Reverts if the caller is not the Standard Governor.\n    modifier onlyStandardGovernor() {\n        _revertIfNotStandardGovernor();\n        _;\n    }\n\n    /* ============ Constructor ============ */\n\n    /**\n     * @notice Constructs a new Power Token contract.\n     * @param  bootstrapToken_   The address of the token to bootstrap balances and voting powers from.\n     * @param  standardGovernor_ The address of the Standard Governor contract to delegate control to.\n     * @param  cashToken_        The address of the token to auction the unowned inflated supply for.\n     * @param  vault_            The address of the vault to transfer cash tokens to.\n     */\n    constructor(\n        address bootstrapToken_,\n        address standardGovernor_,\n        address cashToken_,\n        address vault_\n    ) EpochBasedInflationaryVoteToken(\"Power by M^0\", \"POWER\", 0, ONE / 10) {\n        if ((bootstrapToken = bootstrapToken_) == address(0)) revert InvalidBootstrapTokenAddress();\n        if ((standardGovernor = standardGovernor_) == address(0)) revert InvalidStandardGovernorAddress();\n        if ((_nextCashToken = cashToken_) == address(0)) revert InvalidCashTokenAddress();\n        if ((vault = vault_) == address(0)) revert InvalidVaultAddress();\n\n        uint16 bootstrapEpoch_ = bootstrapEpoch = (_clock() - 1);\n        uint256 bootstrapSupply_ = IEpochBasedVoteToken(bootstrapToken_).pastTotalSupply(bootstrapEpoch_);\n\n        if (bootstrapSupply_ == 0) revert BootstrapSupplyZero();\n\n        if (bootstrapSupply_ > type(uint240).max) revert BootstrapSupplyTooLarge();\n\n        _bootstrapSupply = uint240(bootstrapSupply_);\n\n        _addTotalSupply(INITIAL_SUPPLY);\n\n        // NOTE: For event continuity, the initial supply is dispersed among holders of the bootstrap token.\n        emit Transfer(address(0), bootstrapToken_, INITIAL_SUPPLY);\n    }\n\n    /* ============ Interactive Functions ============ */\n\n    /// @inheritdoc IPowerToken\n    function buy(\n        uint256 minAmount_,\n        uint256 maxAmount_,\n        address destination_,\n        uint16 expiryEpoch_\n    ) external returns (uint240 amount_, uint256 cost_) {\n        // NOTE: Buy order has an epoch-based expiration logic to avoid user's unfair purchases in subsequent auctions.\n        //       Order should be typically valid till the end of current transfer epoch.\n        if (_clock() > expiryEpoch_) revert ExpiredBuyOrder();\n        if (minAmount_ == 0 || maxAmount_ == 0) revert ZeroPurchaseAmount();\n\n        uint240 amountToAuction_ = amountToAuction();\n        uint240 safeMinAmount_ = UIntMath.safe240(minAmount_);\n        uint240 safeMaxAmount_ = UIntMath.safe240(maxAmount_);\n\n        amount_ = amountToAuction_ > safeMaxAmount_ ? safeMaxAmount_ : amountToAuction_;\n\n        if (amount_ < safeMinAmount_) revert InsufficientAuctionSupply(amountToAuction_, safeMinAmount_);\n\n        emit Buy(msg.sender, amount_, cost_ = getCost(amount_));\n\n        _mint(destination_, amount_);\n\n        // NOTE: Not calling `distribute` on vault since anyone can do it, anytime, and this contract should not need to\n        //       know how the vault works\n        if (!ERC20Helper.transferFrom(cashToken(), msg.sender, vault, cost_)) revert TransferFromFailed();\n    }\n\n    /// @inheritdoc IPowerToken\n    function markNextVotingEpochAsActive() external onlyStandardGovernor {\n        // The next voting epoch is the targetEpoch.\n        uint16 currentEpoch_ = _clock();\n        uint16 targetEpoch_ = currentEpoch_ + (_isVotingEpoch(currentEpoch_) ? 2 : 1);\n\n        // If the current epoch is already on or after the `_nextTargetSupplyStartingEpoch`, then rotate the variables\n        // and track the next `_nextTargetSupplyStartingEpoch`, else just overwrite `nextTargetSupply_` only.\n        if (currentEpoch_ >= _nextTargetSupplyStartingEpoch) {\n            _targetSupply = _nextTargetSupply;\n            _nextTargetSupplyStartingEpoch = targetEpoch_;\n        }\n\n        // NOTE: Cap the next target supply at `type(uint240).max`.\n        uint240 nextTargetSupply_ = _nextTargetSupply = UIntMath.bound240(\n            uint256(_targetSupply) + (uint256(_targetSupply) * participationInflation) / ONE\n        );\n\n        emit TargetSupplyInflated(targetEpoch_, nextTargetSupply_);\n    }\n\n    /// @inheritdoc IPowerToken\n    function markParticipation(address delegatee_) external onlyStandardGovernor {\n        _markParticipation(delegatee_);\n    }\n\n    /// @inheritdoc IPowerToken\n    function setNextCashToken(address nextCashToken_) external onlyStandardGovernor {\n        if (nextCashToken_ == address(0)) revert InvalidCashTokenAddress();\n\n        // The next epoch is the targetEpoch.\n        uint16 currentEpoch_ = _clock();\n        uint16 targetEpoch_ = currentEpoch_ + 1;\n\n        // If the current epoch is already on or after the `_nextCashTokenStartingEpoch`, then rotate the variables\n        // and track the next `_nextCashTokenStartingEpoch`, else just overwrite `_nextCashToken` only.\n        if (currentEpoch_ >= _nextCashTokenStartingEpoch) {\n            _cashToken = _nextCashToken;\n            _nextCashTokenStartingEpoch = targetEpoch_;\n        }\n\n        _nextCashToken = nextCashToken_;\n\n        emit NextCashTokenSet(targetEpoch_, _nextCashToken);\n    }\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @inheritdoc IPowerToken\n    function amountToAuction() public view returns (uint240) {\n        if (_isVotingEpoch(_clock())) return 0; // No auction during voting epochs.\n\n        uint240 targetSupply_ = _getTargetSupply();\n        uint240 totalSupply_ = _getTotalSupply(_clock());\n\n        unchecked {\n            return targetSupply_ > totalSupply_ ? targetSupply_ - totalSupply_ : 0;\n        }\n    }\n\n    /// @inheritdoc IPowerToken\n    function cashToken() public view returns (address) {\n        return _clock() >= _nextCashTokenStartingEpoch ? _nextCashToken : _cashToken;\n    }\n\n    /// @inheritdoc IPowerToken\n    function getCost(uint256 amount_) public view returns (uint256) {\n        uint16 currentEpoch_ = _clock();\n\n        uint40 timeRemaining_ = _isVotingEpoch(currentEpoch_)\n            ? PureEpochs.EPOCH_PERIOD\n            : PureEpochs.timeRemainingInCurrentEpoch();\n\n        uint40 secondsPerPeriod_ = PureEpochs.EPOCH_PERIOD / _AUCTION_PERIODS;\n        uint256 leftPoint_ = uint256(1) << (timeRemaining_ / secondsPerPeriod_); // Max is 1 << 100.\n        uint40 remainder_ = timeRemaining_ % secondsPerPeriod_;\n\n        /**\n         * @dev Auction curve:\n         *        - During every auction period (1/100th of an epoch) the price starts at some \"leftPoint\" and decreases\n         *          linearly, with time, to some \"rightPoint\" (which is half of that \"leftPoint\"). This is done by\n         *          computing the weighted average between the \"leftPoint\" and \"rightPoint\" for the time remaining in\n         *          the auction period.\n         *        - For the next auction period, the new \"leftPoint\" is half of the previous period's \"leftPoint\"\n         *          (which also equals the previous period's \"rightPoint\").\n         *        - Combined, this results in the price decreasing by half every auction period at a macro level, but\n         *          decreasing linearly at a micro-level during each period, without any jumps.\n         *      Relative price computation:\n         *        - Since the parameters of this auction are fixed forever (there are no mutable auction parameters and\n         *          this is not an upgradeable contract), and the token supply is expected to increase relatively\n         *          quickly and consistently, the result would be that the price Y for some Z% of the total supply would\n         *          occur earlier and earlier in the auction.\n         *        - Instead, the desired behavior is that after X seconds into the auction, there will be a price Y for\n         *          some Z% of the total supply. In other words, it will always cost 572,662,306,133 cash tokens to buy\n         *          1% of the previous epoch's total supply with 5 days left in the auction period.\n         *        - To achieve this, the price is instead computed per basis point of the last epoch's total supply.\n         */\n        // NOTE: A good amount of this can be done unchecked, but not every step, so it would look messy.\n        return\n            _divideUp(\n                UIntMath.safe240(amount_) *\n                    ((remainder_ * leftPoint_) + ((secondsPerPeriod_ - remainder_) * (leftPoint_ >> 1))),\n                uint256(secondsPerPeriod_) * _getTotalSupply(currentEpoch_ - 1)\n            );\n    }\n\n    /// @inheritdoc IPowerToken\n    function targetSupply() public view returns (uint256) {\n        return _getTargetSupply();\n    }\n\n    /* ============ Internal Interactive Functions ============ */\n\n    /**\n     * @dev   Bootstrap the account's balance and voting power from the bootstrap token.\n     * @param account_ The account to bootstrap.\n     */\n    function _bootstrap(address account_) internal {\n        if (_balances[account_].length != 0) return; // Skip if the account already has synced (and thus bootstrapped).\n\n        uint240 bootstrapBalance_ = _getBootstrapBalance(account_, bootstrapEpoch);\n\n        _balances[account_].push(AmountSnap(bootstrapEpoch, bootstrapBalance_));\n        _votingPowers[account_].push(AmountSnap(bootstrapEpoch, bootstrapBalance_));\n\n        if (bootstrapBalance_ == 0) return;\n\n        // NOTE: For event continuity, the bootstrap token transfers the bootstrap balance to the account.\n        emit Transfer(bootstrapToken, account_, bootstrapBalance_);\n\n        // NOTE: For event continuity, the account's voting power is updated.\n        emit DelegateVotesChanged(account_, 0, bootstrapBalance_);\n    }\n\n    /**\n     * @dev   Delegate voting power from `delegator_` to `newDelegatee_`.\n     * @param delegator_    The address of the account delegating voting power.\n     * @param newDelegatee_ The address of the account receiving voting power.\n     */\n    function _delegate(address delegator_, address newDelegatee_) internal override {\n        if (delegator_ != newDelegatee_) _sync(newDelegatee_);\n\n        super._delegate(delegator_, newDelegatee_);\n    }\n\n    /**\n     * @dev   Syncs `account_` so that its balance Snap array in storage, reflects their unrealized inflation.\n     * @param account_ The address of the account to sync.\n     */\n    function _sync(address account_) internal override {\n        _bootstrap(account_);\n        super._sync(account_);\n    }\n\n    /* ============ Internal View/Pure Functions ============ */\n\n    /**\n     * @dev    Returns the balance of `account_` plus any inflation that is unrealized before `epoch_`.\n     * @param  account_ The account to get the balance for.\n     * @param  epoch_   The epoch to get the balance at.\n     * @return The balance of `account_` plus any inflation that is unrealized before `epoch_`.\n     */\n    function _getBalance(address account_, uint16 epoch_) internal view override returns (uint240) {\n        return _getInternalOrBootstrap(account_, epoch_, super._getBalance);\n    }\n\n    /**\n     * @dev    This is the portion of the initial supply commensurate with\n     *         the account's portion of the bootstrap supply.\n     * @param  account_ The account to get the bootstrap balance for.\n     * @param  epoch_   The epoch to get the bootstrap balance at.\n     * @return The bootstrap balance of `account_` at `epoch_`.\n     */\n    function _getBootstrapBalance(address account_, uint16 epoch_) internal view returns (uint240) {\n        unchecked {\n            // NOTE: Can safely cast `pastBalanceOf` since the constructor already establishes that the total supply of\n            //       the bootstrap token is less than `type(uint240).max`. Can do math unchecked since\n            //       `pastBalanceOf * INITIAL_SUPPLY <= type(uint256).max`.\n            return\n                uint240(\n                    (IEpochBasedVoteToken(bootstrapToken).pastBalanceOf(account_, epoch_) * INITIAL_SUPPLY) /\n                        _bootstrapSupply\n                );\n        }\n    }\n\n    /**\n     * @dev    Returns the total supply at `epoch_`.\n     * @param  epoch_ The epoch to get the total supply at.\n     * @return The total supply at `epoch_`.\n     */\n    function _getTotalSupply(uint16 epoch_) internal view override returns (uint240) {\n        // For epochs before the bootstrap epoch return the initial supply.\n        return epoch_ <= bootstrapEpoch ? INITIAL_SUPPLY : super._getTotalSupply(epoch_);\n    }\n\n    /**\n     * @dev    Returns the amount of votes of `account_` plus any inflation that should be realized at `epoch_`.\n     * @param  account_ The account to get the votes for.\n     * @param  epoch_   The epoch to get the votes at.\n     * @return The votes of `account_` at `epoch_`.\n     */\n    function _getVotes(address account_, uint16 epoch_) internal view override returns (uint240) {\n        return _getInternalOrBootstrap(account_, epoch_, super._getVotes);\n    }\n\n    /**\n     * @dev    Returns the amount of balance/votes for `account_` at clock value `epoch_`.\n     * @param  account_ The account to get the balance/votes for.\n     * @param  epoch_   The epoch to get the balance/votes at.\n     * @param  getter_  An internal view function that returns the balance/votes that are internally tracked.\n     * @return The balance/votes of `account_` (plus any inflation that should be realized) at `epoch_`.\n     */\n    function _getInternalOrBootstrap(\n        address account_,\n        uint16 epoch_,\n        function(address, uint16) internal view returns (uint240) getter_\n    ) internal view returns (uint240) {\n        // For epochs less than or equal to the bootstrap epoch, return the bootstrap balance at that epoch.\n        if (epoch_ <= bootstrapEpoch) return _getBootstrapBalance(account_, epoch_);\n\n        // If no syncs, return the bootstrap balance at the bootstrap epoch.\n        // NOTE: There cannot yet be any unrealized inflation after the bootstrap epoch since receiving, sending,\n        //       delegating, or having participation marked would have resulted in a `_bootstrap`, and thus some snaps.\n        if (_balances[account_].length == 0) return _getBootstrapBalance(account_, bootstrapEpoch);\n\n        return getter_(account_, epoch_);\n    }\n\n    /**\n     * @dev    Returns the epoch of the last sync of `account_` at or before `epoch_`.\n     * @param  account_ The account to get the last sync for.\n     * @param  epoch_   The epoch to get the last sync at or before.\n     * @return The epoch of the last sync of `account_` at or before `epoch_`.\n     */\n    function _getLastSync(address account_, uint16 epoch_) internal view override returns (uint16) {\n        // If there are no balance snaps, return the bootstrap epoch.\n        return (_balances[account_].length == 0) ? bootstrapEpoch : super._getLastSync(account_, epoch_);\n    }\n\n    /// @dev Returns the target supply of the token at the current epoch.\n    function _getTargetSupply() internal view returns (uint240) {\n        return _clock() >= _nextTargetSupplyStartingEpoch ? _nextTargetSupply : _targetSupply;\n    }\n\n    /// @dev Reverts if the caller is not the Standard Governor.\n    function _revertIfNotStandardGovernor() internal view {\n        if (msg.sender != standardGovernor) revert NotStandardGovernor();\n    }\n\n    /**\n     * @dev Helper function to calculate `x` / `y`, rounded up.\n     * @dev Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)\n     */\n    function _divideUp(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        if (y == 0) revert DivisionByZero();\n\n        if (x == 0) return 0;\n\n        z = (x * ONE) + y;\n\n        unchecked {\n            z = (z - 1) / y;\n        }\n    }\n}\n"
      },
      "lib/ttg/src/interfaces/IDeployer.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\n/**\n * @title  A Deterministic deployer of contracts using CREATE.\n * @author M^0 Labs\n */\ninterface IDeployer {\n    /// @notice Returns the nonce used to pre deterministically compute the address of the next deployed contract.\n    function nonce() external view returns (uint256);\n\n    /// @notice Returns the address of the last contract deployed by this contract.\n    function lastDeploy() external view returns (address);\n\n    /// @notice Returns the address of the next contract this contract will deploy.\n    function nextDeploy() external view returns (address);\n}\n"
      },
      "lib/ttg/lib/erc20-helper/src/ERC20Helper.sol": {
        "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity ^0.8.7;\n\nimport { IERC20Like } from \"./interfaces/IERC20Like.sol\";\n\n/**\n * @title Small Library to standardize erc20 token interactions.\n */\nlibrary ERC20Helper {\n\n    /**************************************************************************************************************************************/\n    /*** Internal Functions                                                                                                             ***/\n    /**************************************************************************************************************************************/\n\n    function transfer(address token_, address to_, uint256 amount_) internal returns (bool success_) {\n        return _call(token_, abi.encodeWithSelector(IERC20Like.transfer.selector, to_, amount_));\n    }\n\n    function transferFrom(address token_, address from_, address to_, uint256 amount_) internal returns (bool success_) {\n        return _call(token_, abi.encodeWithSelector(IERC20Like.transferFrom.selector, from_, to_, amount_));\n    }\n\n    function approve(address token_, address spender_, uint256 amount_) internal returns (bool success_) {\n        // If setting approval to zero fails, return false.\n        if (!_call(token_, abi.encodeWithSelector(IERC20Like.approve.selector, spender_, uint256(0)))) return false;\n\n        // If `amount_` is zero, return true as the previous step already did this.\n        if (amount_ == uint256(0)) return true;\n\n        // Return the result of setting the approval to `amount_`.\n        return _call(token_, abi.encodeWithSelector(IERC20Like.approve.selector, spender_, amount_));\n    }\n\n    function _call(address token_, bytes memory data_) private returns (bool success_) {\n        if (token_.code.length == uint256(0)) return false;\n\n        bytes memory returnData;\n        ( success_, returnData ) = token_.call(data_);\n\n        return success_ && (returnData.length == uint256(0) || abi.decode(returnData, (bool)));\n    }\n\n}\n"
      },
      "lib/ttg/lib/common/src/libs/UIntMath.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\n/**\n * @title  Library to perform safe math operations on uint types\n * @author M^0 Labs\n */\nlibrary UIntMath {\n    /* ============ Custom Errors ============ */\n\n    /// @notice Emitted when a passed value is greater than the maximum value of uint16.\n    error InvalidUInt16();\n\n    /// @notice Emitted when a passed value is greater than the maximum value of uint40.\n    error InvalidUInt40();\n\n    /// @notice Emitted when a passed value is greater than the maximum value of uint48.\n    error InvalidUInt48();\n\n    /// @notice Emitted when a passed value is greater than the maximum value of uint112.\n    error InvalidUInt112();\n\n    /// @notice Emitted when a passed value is greater than the maximum value of uint128.\n    error InvalidUInt128();\n\n    /// @notice Emitted when a passed value is greater than the maximum value of uint240.\n    error InvalidUInt240();\n\n    /* ============ Internal View/Pure Functions ============ */\n\n    /**\n     * @notice Casts a given uint256 value to a uint16,\n     *         ensuring that it is less than or equal to the maximum uint16 value.\n     * @param  n The value to check.\n     * @return The value casted to uint16.\n     */\n    function safe16(uint256 n) internal pure returns (uint16) {\n        if (n > type(uint16).max) revert InvalidUInt16();\n        return uint16(n);\n    }\n\n    /**\n     * @notice Casts a given uint256 value to a uint40,\n     *         ensuring that it is less than or equal to the maximum uint40 value.\n     * @param  n The value to check.\n     * @return The value casted to uint40.\n     */\n    function safe40(uint256 n) internal pure returns (uint40) {\n        if (n > type(uint40).max) revert InvalidUInt40();\n        return uint40(n);\n    }\n\n    /**\n     * @notice Casts a given uint256 value to a uint48,\n     *         ensuring that it is less than or equal to the maximum uint48 value.\n     * @param  n The value to check.\n     * @return The value casted to uint48.\n     */\n    function safe48(uint256 n) internal pure returns (uint48) {\n        if (n > type(uint48).max) revert InvalidUInt48();\n        return uint48(n);\n    }\n\n    /**\n     * @notice Casts a given uint256 value to a uint112,\n     *         ensuring that it is less than or equal to the maximum uint112 value.\n     * @param  n The value to check.\n     * @return The value casted to uint112.\n     */\n    function safe112(uint256 n) internal pure returns (uint112) {\n        if (n > type(uint112).max) revert InvalidUInt112();\n        return uint112(n);\n    }\n\n    /**\n     * @notice Casts a given uint256 value to a uint128,\n     *         ensuring that it is less than or equal to the maximum uint128 value.\n     * @param  n The value to check.\n     * @return The value casted to uint128.\n     */\n    function safe128(uint256 n) internal pure returns (uint128) {\n        if (n > type(uint128).max) revert InvalidUInt128();\n        return uint128(n);\n    }\n\n    /**\n     * @notice Casts a given uint256 value to a uint240,\n     *         ensuring that it is less than or equal to the maximum uint240 value.\n     * @param  n The value to check.\n     * @return The value casted to uint240.\n     */\n    function safe240(uint256 n) internal pure returns (uint240) {\n        if (n > type(uint240).max) revert InvalidUInt240();\n        return uint240(n);\n    }\n\n    /**\n     * @notice Limits a given uint256 value to the maximum uint32 value.\n     * @param  n The value to check.\n     * @return The value limited to within uint32 bounds.\n     */\n    function bound32(uint256 n) internal pure returns (uint32) {\n        return uint32(min256(n, uint256(type(uint32).max)));\n    }\n\n    /**\n     * @notice Limits a given uint256 value to the maximum uint112 value.\n     * @param  n The value to check.\n     * @return The value limited to within uint112 bounds.\n     */\n    function bound112(uint256 n) internal pure returns (uint112) {\n        return uint112(min256(n, uint256(type(uint112).max)));\n    }\n\n    /**\n     * @notice Limits a given uint256 value to the maximum uint128 value.\n     * @param  n The value to check.\n     * @return The value limited to within uint128 bounds.\n     */\n    function bound128(uint256 n) internal pure returns (uint128) {\n        return uint128(min256(n, uint256(type(uint128).max)));\n    }\n\n    /**\n     * @notice Limits a given uint256 value to the maximum uint240 value.\n     * @param  n The value to check.\n     * @return The value limited to within uint240 bounds.\n     */\n    function bound240(uint256 n) internal pure returns (uint240) {\n        return uint240(min256(n, uint256(type(uint240).max)));\n    }\n\n    /**\n     * @notice Compares two uint32 values and returns the larger one.\n     * @param  a_  Value to check.\n     * @param  b_  Value to check.\n     * @return The larger value.\n     */\n    function max32(uint32 a_, uint32 b_) internal pure returns (uint32) {\n        return a_ > b_ ? a_ : b_;\n    }\n\n    /**\n     * @notice Compares two uint40 values and returns the larger one.\n     * @param  a_  Value to check.\n     * @param  b_  Value to check.\n     * @return The larger value.\n     */\n    function max40(uint40 a_, uint40 b_) internal pure returns (uint40) {\n        return a_ > b_ ? a_ : b_;\n    }\n\n    /**\n     * @notice Compares two uint32 values and returns the lesser one.\n     * @param  a_  Value to check.\n     * @param  b_  Value to check.\n     * @return The lesser value.\n     */\n    function min32(uint32 a_, uint32 b_) internal pure returns (uint32) {\n        return a_ < b_ ? a_ : b_;\n    }\n\n    /**\n     * @notice Compares two uint40 values and returns the lesser one.\n     * @param  a_  Value to check.\n     * @param  b_  Value to check.\n     * @return The lesser value.\n     */\n    function min40(uint40 a_, uint40 b_) internal pure returns (uint40) {\n        return a_ < b_ ? a_ : b_;\n    }\n\n    /**\n     * @notice Compares two uint240 values and returns the lesser one.\n     * @param  a_  Value to check.\n     * @param  b_  Value to check.\n     * @return The lesser value.\n     */\n    function min240(uint240 a_, uint240 b_) internal pure returns (uint240) {\n        return a_ < b_ ? a_ : b_;\n    }\n\n    /**\n     * @notice Compares two uint112 values and returns the lesser one.\n     * @param  a_  Value to check.\n     * @param  b_  Value to check.\n     * @return The lesser value.\n     */\n    function min112(uint112 a_, uint112 b_) internal pure returns (uint112) {\n        return a_ < b_ ? a_ : b_;\n    }\n\n    /**\n     * @notice Compares two uint256 values and returns the lesser one.\n     * @param  a_  Value to check.\n     * @param  b_  Value to check.\n     * @return The lesser value.\n     */\n    function min256(uint256 a_, uint256 b_) internal pure returns (uint256) {\n        return a_ < b_ ? a_ : b_;\n    }\n}\n"
      },
      "lib/ttg/src/libs/PureEpochs.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\n/**\n * @notice Defines epochs as periods away from STARTING_TIMESTAMP timestamp.\n * @author M^0 Labs\n * @dev    Provides a `uint16` epoch clock value.\n */\nlibrary PureEpochs {\n    /* ============ Variables ============ */\n\n    /// @notice The timestamp of the start of Epoch 1.\n    uint40 internal constant STARTING_TIMESTAMP = 1713099600;\n\n    /// @notice The approximate target of seconds an epoch should endure.\n    uint40 internal constant EPOCH_PERIOD = 1296000;\n\n    /* ============ Internal View/Pure Functions ============ */\n\n    /// @dev Returns the current epoch number.\n    function currentEpoch() internal view returns (uint16) {\n        return uint16(((block.timestamp - STARTING_TIMESTAMP) / EPOCH_PERIOD) + 1);\n    }\n\n    /// @dev Returns the remaining time in the current epoch.\n    function timeRemainingInCurrentEpoch() internal view returns (uint40) {\n        return STARTING_TIMESTAMP + (currentEpoch() * EPOCH_PERIOD) - uint40(block.timestamp);\n    }\n\n    function clockMode() internal pure returns (string memory) {\n        return \"mode=epoch&epochUnderlyingSource=blockTimestamp&epochStartingTimestamp=1713099600&epochPeriod=1296000\";\n    }\n}\n"
      },
      "lib/ttg/src/abstract/interfaces/IEpochBasedVoteToken.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\nimport { IERC20Extended } from \"../../../lib/common/src/interfaces/IERC20Extended.sol\";\n\nimport { IERC5805 } from \"./IERC5805.sol\";\n\n/**\n * @title  Extension for an ERC5805 token that uses epochs as its clock mode and delegation via IERC1271.\n * @author M^0 Labs\n */\ninterface IEpochBasedVoteToken is IERC5805, IERC20Extended {\n    /* ============ Custom Errors ============ */\n\n    /// @notice Revert message when the provided epoch is zero.\n    error EpochZero();\n\n    /* ============ Interactive Functions ============ */\n\n    /**\n     * @notice Changes the voting power delegation for `account` to `delegatee`.\n     * @param  account   The purported address of the signing account.\n     * @param  delegatee The address the voting power of `account` will be delegated to.\n     * @param  nonce     The nonce used for the signature.\n     * @param  expiry    The timestamp until which the signature is still valid.\n     * @param  signature A byte array signature.\n     */\n    function delegateBySig(\n        address account,\n        address delegatee,\n        uint256 nonce,\n        uint256 expiry,\n        bytes memory signature\n    ) external;\n\n    /* ============ View/Pure Functions ============ */\n\n    /**\n     * @notice Returns the digest to be signed, via EIP-712, given an internal digest (i.e. hash struct).\n     * @param  delegatee The address of the delegatee to delegate to.\n     * @param  nonce     The nonce of the account delegating.\n     * @param  expiry    The timestamp until which the signature is still valid.\n     * @return The digest to be signed.\n     */\n    function getDelegationDigest(address delegatee, uint256 nonce, uint256 expiry) external view returns (bytes32);\n\n    /**\n     * @notice Returns the token balance of `account` at a past clock value `epoch`.\n     * @param  account The address of some account.\n     * @param  epoch   The epoch number as a clock value.\n     * @return The token balance `account` at `epoch`.\n     */\n    function pastBalanceOf(address account, uint256 epoch) external view returns (uint256);\n\n    /**\n     * @notice Returns the delegatee of `account` at a past clock value `epoch`.\n     * @param  account The address of some account.\n     * @param  epoch   The epoch number as a clock value.\n     * @return The delegatee of the voting power of `account` at `epoch`.\n     */\n    function pastDelegates(address account, uint256 epoch) external view returns (address);\n\n    /**\n     * @notice Returns the total token supply at a past clock value `epoch`.\n     * @param  epoch The epoch number as a clock value.\n     * @return The total token supply at `epoch`.\n     */\n    function pastTotalSupply(uint256 epoch) external view returns (uint256);\n}\n"
      },
      "lib/ttg/src/abstract/EpochBasedInflationaryVoteToken.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\nimport { UIntMath } from \"../../lib/common/src/libs/UIntMath.sol\";\n\nimport { IEpochBasedInflationaryVoteToken } from \"./interfaces/IEpochBasedInflationaryVoteToken.sol\";\n\nimport { EpochBasedVoteToken } from \"./EpochBasedVoteToken.sol\";\n\n// NOTE: There is no feasible way to emit `Transfer` events for inflationary minting such that external client can\n//       index them and track balances and total supply correctly. Specifically, and only for total supply indexing, one\n//       can assume that total supply is the sum of all voting powers, thus tracking the deltas of the\n//       `DelegateVotesChanged` events will suffice.\n\n/**\n * @title  Extension for an EpochBasedVoteToken token that allows for inflating tokens and voting power.\n * @author M^0 Labs\n */\nabstract contract EpochBasedInflationaryVoteToken is IEpochBasedInflationaryVoteToken, EpochBasedVoteToken {\n    /* ============ Structs ============ */\n\n    /// @dev A 32-byte struct containing a starting epoch that merely marks that something occurred in this epoch.\n    struct VoidSnap {\n        uint16 startingEpoch;\n    }\n\n    /* ============ Variables ============ */\n\n    /// @inheritdoc IEpochBasedInflationaryVoteToken\n    uint16 public constant ONE = 10_000; // 100% in basis points.\n\n    /// @inheritdoc IEpochBasedInflationaryVoteToken\n    uint16 public immutable participationInflation; // In basis points.\n\n    /// @dev A mapping of delegatees to their participation snaps, marking epochs in which they have participated.\n    mapping(address delegatee => VoidSnap[] participationSnaps) internal _participations;\n\n    /* ============ Modifiers ============ */\n\n    /// @dev Reverts if the current epoch is a voting epoch.\n    modifier notDuringVoteEpoch() {\n        _revertIfInVoteEpoch();\n        _;\n    }\n\n    /// @dev Reverts if the current epoch is not a voting epoch.\n    modifier onlyDuringVoteEpoch() {\n        _revertIfNotInVoteEpoch();\n        _;\n    }\n\n    /* ============ Constructor ============ */\n\n    /**\n     * @notice Constructs a new EpochBasedInflationaryVoteToken contract.\n     * @param  name_                   The name of the token.\n     * @param  symbol_                 The symbol of the token.\n     * @param  decimals_               The decimals of the token.\n     * @param  participationInflation_ The participation inflation rate used to inflate tokens for participation.\n     */\n    constructor(\n        string memory name_,\n        string memory symbol_,\n        uint8 decimals_,\n        uint16 participationInflation_\n    ) EpochBasedVoteToken(name_, symbol_, decimals_) {\n        if (participationInflation_ > ONE) revert InflationTooHigh();\n\n        participationInflation = participationInflation_;\n    }\n\n    /* ============ Interactive Functions ============ */\n\n    /// @inheritdoc IEpochBasedInflationaryVoteToken\n    function sync(address account_) external {\n        _sync(account_);\n\n        emit Sync(account_);\n    }\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @inheritdoc IEpochBasedInflationaryVoteToken\n    function hasParticipatedAt(address delegatee_, uint256 epoch_) external view returns (bool) {\n        return _hasParticipatedAt(delegatee_, UIntMath.safe16(epoch_));\n    }\n\n    /* ============ Internal Interactive Functions ============ */\n\n    /**\n     * @dev   Delegate voting power from `delegator_` to `newDelegatee_`.\n     * @dev   The inflation is first realized according to participation of the current delegatee by calling `_sync()`.\n     * @param delegator_    The address of the account delegating voting power.\n     * @param newDelegatee_ The address of the account receiving voting power.\n     */\n    function _delegate(address delegator_, address newDelegatee_) internal virtual override notDuringVoteEpoch {\n        _sync(delegator_);\n        super._delegate(delegator_, newDelegatee_);\n    }\n\n    /**\n     * @dev   Allows for the inflation of a delegatee's voting power (and total supply) up to one time per epoch.\n     * @param delegatee_ The address of the account being marked as having participated.\n     */\n    function _markParticipation(address delegatee_) internal onlyDuringVoteEpoch {\n        uint16 currentEpoch_ = _clock();\n\n        // Revert if could not update, as it means the delegatee has already participated in this epoch.\n        if (!_update(_participations[delegatee_], currentEpoch_)) revert AlreadyParticipated();\n\n        _sync(delegatee_);\n\n        uint240 inflation_ = _getInflation(_getVotes(delegatee_, currentEpoch_));\n\n        if (inflation_ != 0) emit Transfer(address(0), address(this), inflation_);\n\n        _addTotalSupply(inflation_);\n        _addVotingPower(delegatee_, inflation_);\n    }\n\n    /**\n     * @dev   Mint `amount_` tokens to `recipient_`.\n     * @param recipient_ The address of the account to mint tokens to.\n     * @param amount_    The amount of tokens to mint.\n     */\n    function _mint(address recipient_, uint256 amount_) internal override notDuringVoteEpoch {\n        _sync(recipient_);\n        super._mint(recipient_, amount_);\n    }\n\n    /**\n     * @dev   Syncs `account_` so that its balance Snap array in storage, reflects their unrealized inflation.\n     * @param account_ The address of the account to sync.\n     */\n    function _sync(address account_) internal virtual {\n        uint240 inflation_ = _getUnrealizedInflation(account_, _clock());\n\n        if (inflation_ != 0) emit Transfer(address(this), account_, inflation_);\n\n        // Realized the account's unrealized inflation since its last sync.\n        _addBalance(account_, inflation_);\n    }\n\n    /**\n     * @dev Transfers `amount_` tokens from `sender_` to `recipient_`.\n     * @param sender_    The address of the account to transfer tokens from.\n     * @param recipient_ The address of the account to transfer tokens to.\n     * @param amount_    The amount of tokens to transfer.\n     */\n    function _transfer(address sender_, address recipient_, uint256 amount_) internal override notDuringVoteEpoch {\n        _sync(sender_);\n\n        if (recipient_ != sender_) _sync(recipient_);\n\n        super._transfer(sender_, recipient_, amount_);\n    }\n\n    /**\n     * @dev    Update a storage VoidSnap array to contain the current epoch as the latest snap.\n     * @param  voidSnaps_ The storage pointer to a VoidSnap array to update.\n     * @param  epoch_     The epoch to write as the latest element of the VoidSnap array.\n     * @return updated_   Whether the VoidSnap array was updated, and thus did not already contain the current epoch.\n     */\n    function _update(VoidSnap[] storage voidSnaps_, uint16 epoch_) internal returns (bool updated_) {\n        uint256 length_ = voidSnaps_.length;\n\n        unchecked {\n            // If this will be the first or a new VoidSnap, just push it onto the array.\n            if (updated_ = ((length_ == 0) || (epoch_ > _unsafeAccess(voidSnaps_, length_ - 1).startingEpoch))) {\n                voidSnaps_.push(VoidSnap(epoch_));\n            }\n        }\n    }\n\n    /* ============ Internal View/Pure Functions ============ */\n\n    /**\n     * @dev    Returns the balance of `account_` plus any inflation that in unrealized before `epoch_`.\n     * @param  account_ The account to get the balance for.\n     * @param  epoch_   The epoch to get the balance at.\n     * @return The balance of `account_` plus any inflation that is unrealized before `epoch_`.\n     */\n    function _getBalance(address account_, uint16 epoch_) internal view virtual override returns (uint240) {\n        unchecked {\n            return\n                UIntMath.bound240(\n                    uint256(super._getBalance(account_, epoch_)) + _getUnrealizedInflation(account_, epoch_)\n                );\n        }\n    }\n\n    /**\n     * @dev    Returns the balance of `account_` at `epoch_` without any unrealized inflation.\n     * @param  account_ The account to get the balance for.\n     * @param  epoch_   The epoch to get the balance at.\n     * @return The balance of `account_` at `epoch` without any unrealized inflation.\n     */\n    function _getBalanceWithoutUnrealizedInflation(\n        address account_,\n        uint16 epoch_\n    ) internal view virtual returns (uint240) {\n        return super._getBalance(account_, epoch_);\n    }\n\n    /**\n     * @dev    Returns the inflation of `amount` due to participation inflation.\n     * @param  amount_ The amount to determine inflation for.\n     * @return The inflation of `amount` due to participation inflation.\n     */\n    function _getInflation(uint240 amount_) internal view returns (uint240) {\n        unchecked {\n            return uint240((uint256(amount_) * participationInflation) / ONE); // Cannot overflow.\n        }\n    }\n\n    /**\n     * @dev    Returns the epoch of the last sync of `account_` at or before `epoch_`.\n     *         Override this function in order to return the \"default\"/starting epoch if the account has never synced.\n     * @param  account_ The account to get the last sync for.\n     * @param  epoch_   The epoch to get the last sync at or before.\n     * @return The epoch of the last sync of `account_` at or before `epoch_`.\n     */\n    function _getLastSync(address account_, uint16 epoch_) internal view virtual returns (uint16) {\n        if (epoch_ == 0) revert EpochZero();\n\n        AmountSnap[] storage amountSnaps_ = _balances[account_];\n\n        uint256 index_ = amountSnaps_.length; // NOTE: `index_` starts out as length, and would be out of bounds.\n\n        // Keep going back until we find the first snap with a startingEpoch less than or equal to `epoch_`. This snap\n        // is the most recent to `epoch_`, so return its startingEpoch. If we exhaust the array, then it's 0.\n        while (index_ > 0) {\n            unchecked {\n                uint16 snapStartingEpoch_ = _unsafeAccess(amountSnaps_, --index_).startingEpoch;\n\n                if (snapStartingEpoch_ <= epoch_) return snapStartingEpoch_;\n            }\n        }\n\n        return 0;\n    }\n\n    /**\n     * @dev    Returns whether `delegatee_` has participated during the clock value `epoch_`.\n     * @param  delegatee_ The account whose participation is being queried.\n     * @param  epoch_     The epoch at which to determine participation.\n     * @return Whether `delegatee_` has participated during the clock value `epoch_`.\n     */\n    function _hasParticipatedAt(address delegatee_, uint16 epoch_) internal view returns (bool) {\n        if (epoch_ == 0) revert EpochZero();\n\n        VoidSnap[] storage voidSnaps_ = _participations[delegatee_];\n\n        uint256 index_ = voidSnaps_.length; // NOTE: `index_` starts out as length, and would be out of bounds.\n\n        // Keep going back until we find the first snap with a startingEpoch less than or equal to `epoch_`.\n        // If this snap's startingEpoch is equal to `epoch_`, it means the delegatee did participate in `epoch_`.\n        // If this startingEpoch is less than `epoch_`, it means the delegatee did not participated in `epoch_`.\n        // If we exhaust the array, then the delegatee never participated in any epoch prior to `epoch_`.\n        while (index_ > 0) {\n            unchecked {\n                uint16 snapStartingEpoch_ = _unsafeAccess(voidSnaps_, --index_).startingEpoch;\n\n                if (snapStartingEpoch_ > epoch_) continue;\n\n                return snapStartingEpoch_ == epoch_;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * @dev    Returns the unrealized inflation for `account_` from their last sync to the epoch before `lastEpoch_`.\n     * @param  account_   The account being queried.\n     * @param  lastEpoch_ The last epoch at which to determine unrealized inflation, not inclusive.\n     * @return inflation_ The total unrealized inflation that has yet to be synced.\n     */\n    function _getUnrealizedInflation(address account_, uint16 lastEpoch_) internal view returns (uint240 inflation_) {\n        // The balance and delegatee the account had at the epoch are the same since the last sync (by definition).\n        uint240 balance_ = _getBalanceWithoutUnrealizedInflation(account_, lastEpoch_);\n\n        if (balance_ == 0) return 0; // No inflation if the account had no balance.\n\n        uint256 inflatedBalance_ = balance_;\n\n        // NOTE: Only need to check if the latest delegatee has participated, since the inflation from any previous\n        //       delegatee would have been synced (realized) in most recent re-delegation (see `_delegate()`).\n        address delegatee_ = _getDelegatee(account_, lastEpoch_); // Internal avoids `_revertIfNotPastTimepoint`.\n\n        // NOTE: Starting from the epoch after the latest sync and looping through the subsequent epochs until (but not\n        //       including) `lastEpoch_`, to get the unrealized inflation.\n        // NOTE: If account never synced (i.e. it never interacted with the contract nor received tokens or voting\n        //       power), then `epoch_` will start at 0, which can result in a longer loop than needed. Inheriting\n        //       contracts should override `_getLastSync` to return the most recent appropriate epoch for such an\n        //       account, such as the epoch when the contract was deployed, some bootstrap epoch, etc.\n        for (uint16 epoch_ = _getLastSync(account_, lastEpoch_); epoch_ < lastEpoch_; ++epoch_) {\n            // Skip non-voting epochs and epochs when the delegatee did not participate.\n            if (!_isVotingEpoch(epoch_) || !_hasParticipatedAt(delegatee_, epoch_)) continue;\n\n            unchecked {\n                inflatedBalance_ += _getInflation(uint240(inflatedBalance_));\n\n                // Cap inflation to `type(uint240).max`.\n                if (inflatedBalance_ >= type(uint240).max) return type(uint240).max - balance_;\n            }\n        }\n\n        return uint240(inflatedBalance_ - balance_);\n    }\n\n    /// @dev Reverts if the current epoch is a voting epoch.\n    function _revertIfInVoteEpoch() internal view {\n        if (_isVotingEpoch(_clock())) revert VoteEpoch();\n    }\n\n    /// @dev Reverts if the current epoch is not a voting epoch.\n    function _revertIfNotInVoteEpoch() internal view {\n        if (!_isVotingEpoch(_clock())) revert NotVoteEpoch();\n    }\n\n    /**\n     * @dev    Returns whether the clock value `epoch_` is a voting epoch or not.\n     * @param  epoch_ Some clock value.\n     * @return Whether the epoch is a voting epoch.\n     */\n    function _isVotingEpoch(uint16 epoch_) internal pure returns (bool) {\n        return epoch_ % 2 == 1; // Voting epochs are odd numbered.\n    }\n\n    /**\n     * @dev    Returns the VoidSnap in an array at a given index without doing bounds checking.\n     * @param  voidSnaps_ The array of VoidSnaps to parse.\n     * @param  index_     The index of the VoidSnap to return.\n     * @return voidSnap_  The VoidSnap at `index_`.\n     */\n    function _unsafeAccess(\n        VoidSnap[] storage voidSnaps_,\n        uint256 index_\n    ) internal pure returns (VoidSnap storage voidSnap_) {\n        assembly {\n            mstore(0, voidSnaps_.slot)\n            voidSnap_.slot := add(keccak256(0, 0x20), index_)\n        }\n    }\n}\n"
      },
      "lib/ttg/src/interfaces/IPowerToken.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\nimport { IEpochBasedInflationaryVoteToken } from \"../abstract/interfaces/IEpochBasedInflationaryVoteToken.sol\";\n\n/**\n * @title  An instance of an EpochBasedInflationaryVoteToken delegating control to a Standard Governor,\n *         and enabling auctioning of the unowned inflated supply.\n * @author M^0 Labs\n */\ninterface IPowerToken is IEpochBasedInflationaryVoteToken {\n    /* ============ Events ============ */\n\n    /**\n     * @notice Emitted when `buyer` has bought `amount` tokens from the auction, as a total cash token value of `cost`.\n     * @param  buyer  The address of account that bought tokens from the auction.\n     * @param  amount The amount of tokens bought.\n     * @param  cost   The total cash token cost of the purchase.\n     */\n    event Buy(address indexed buyer, uint240 amount, uint256 cost);\n\n    /**\n     * @notice Emitted when the cash token is queued to become `nextCashToken` at the start of epoch `startingEpoch`.\n     * @param  startingEpoch The epoch number as a clock value in which the new cash token takes effect.\n     * @param  nextCashToken The address of the cash token taking effect at `startingEpoch`.\n     */\n    event NextCashTokenSet(uint16 indexed startingEpoch, address indexed nextCashToken);\n\n    /**\n     * @notice Emitted in the constructor at deployment.\n     * @param  tagline The tagline of the contract.\n     */\n    event Tagline(string tagline);\n\n    /**\n     * @notice Emitted when the target supply is queued to become `targetSupply` at the start of epoch `targetEpoch`.\n     * @param  targetEpoch  The epoch number as a clock value in which the new target supply takes effect.\n     * @param  targetSupply The target supply taking effect at `startingEpoch`.\n     */\n    event TargetSupplyInflated(uint16 indexed targetEpoch, uint240 indexed targetSupply);\n\n    /* ============ Custom Errors ============ */\n\n    /// @notice Revert message when the total supply of the bootstrap token is larger than `type(uint240).max`.\n    error BootstrapSupplyTooLarge();\n\n    /// @notice Revert message when the total supply of the bootstrap token is 0.\n    error BootstrapSupplyZero();\n\n    /**\n     * @notice Revert message when the amount available for auction is less than the minimum requested to buy.\n     * @param  amountToAuction    The amount available for auction.\n     * @param  minAmountRequested The minimum amount that was requested to buy.\n     */\n    error InsufficientAuctionSupply(uint240 amountToAuction, uint240 minAmountRequested);\n\n    /// @notice Revert message when the Bootstrap Token specified in the constructor is address(0).\n    error InvalidBootstrapTokenAddress();\n\n    /// @notice Revert message when the Cash Token specified in the constructor is address(0).\n    error InvalidCashTokenAddress();\n\n    /// @notice Revert message when the Standard Governor specified in the constructor is address(0).\n    error InvalidStandardGovernorAddress();\n\n    /// @notice Revert message when the Vault specified in the constructor is address(0).\n    error InvalidVaultAddress();\n\n    /// @notice Revert message when the caller is not the Standard Governor.\n    error NotStandardGovernor();\n\n    /// @notice Revert message when a token transferFrom fails.\n    error TransferFromFailed();\n\n    /// @notice Revert message when auction calculations use zero as denominator.\n    error DivisionByZero();\n\n    /// @notice Revert message when the buy order has expired using epoch-based expiration clock.\n    error ExpiredBuyOrder();\n\n    /// @notice Revert message when the buy order has zero maximum and minimum amounts.\n    error ZeroPurchaseAmount();\n\n    /**\n     * @notice Revert message when trying to sync to an epoch that is before the bootstrap epoch.\n     * @param  bootstrapEpoch The bootstrap epoch.\n     * @param  epoch          The epoch attempting to be synced to, not inclusively.\n     */\n    error SyncBeforeBootstrap(uint16 bootstrapEpoch, uint16 epoch);\n\n    /* ============ Interactive Functions ============ */\n\n    /**\n     * @notice Allows a caller to buy `amount` tokens from the auction.\n     * @param  minAmount   The minimum amount of tokens the caller is interested in buying.\n     * @param  maxAmount   The maximum amount of tokens the caller is interested in buying.\n     * @param  destination The address of the account to send the bought tokens.\n     * @param  expiryEpoch The epoch number at the end of which the buy order expires.\n     * @return amount      The amount of token bought.\n     * @return cost        The total cash token cost of the purchase.\n     */\n    function buy(\n        uint256 minAmount,\n        uint256 maxAmount,\n        address destination,\n        uint16 expiryEpoch\n    ) external returns (uint240 amount, uint256 cost);\n\n    /// @notice Marks the next voting epoch as targeted for inflation.\n    function markNextVotingEpochAsActive() external;\n\n    /**\n     * @notice Marks `delegatee` as having participated in the current epoch, thus receiving voting power inflation.\n     * @param  delegatee The address of the account being marked as having participated.\n     */\n    function markParticipation(address delegatee) external;\n\n    /**\n     * @notice Queues the cash token that will take effect from the next epoch onward.\n     * @param  nextCashToken The address of the cash token taking effect from the next epoch onward.\n     */\n    function setNextCashToken(address nextCashToken) external;\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @notice Returns the amount of tokens that can be bought in the auction.\n    function amountToAuction() external view returns (uint240);\n\n    /// @notice Returns the epoch from which token balances and voting powers are bootstrapped.\n    function bootstrapEpoch() external view returns (uint16);\n\n    /// @notice Returns the address of the token in which token balances and voting powers are bootstrapped.\n    function bootstrapToken() external view returns (address);\n\n    /// @notice Returns the address of the cash token required to buy from the token auction.\n    function cashToken() external view returns (address);\n\n    /**\n     * @notice Returns the total cost, in cash token, of purchasing `amount` tokens from the auction.\n     * @param  amount Some amount of tokens.\n     * @return The total cost, in cash token, of `amount` tokens.\n     */\n    function getCost(uint256 amount) external view returns (uint256);\n\n    /// @notice Returns the address of the Standard Governor.\n    function standardGovernor() external view returns (address);\n\n    /// @notice Returns the target supply, which helps determine the amount of tokens up for auction.\n    function targetSupply() external view returns (uint256);\n\n    /// @notice Returns the address of the Vault.\n    function vault() external view returns (address);\n\n    /// @notice Returns the initial supply of the token.\n    function INITIAL_SUPPLY() external pure returns (uint240);\n}\n"
      },
      "lib/ttg/lib/erc20-helper/src/interfaces/IERC20Like.sol": {
        "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity ^0.8.7;\n\n/// @title Interface of the ERC20 standard as needed by ERC20Helper.\ninterface IERC20Like {\n\n    function approve(address spender_, uint256 amount_) external returns (bool success_);\n\n    function transfer(address recipient_, uint256 amount_) external returns (bool success_);\n\n    function transferFrom(address owner_, address recipient_, uint256 amount_) external returns (bool success_);\n\n}\n"
      },
      "lib/ttg/lib/common/src/interfaces/IERC20Extended.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\nimport { IERC20 } from \"./IERC20.sol\";\nimport { IERC3009 } from \"./IERC3009.sol\";\n\n/**\n * @title  An ERC20 token extended with EIP-2612 permits for signed approvals (via EIP-712\n *         and with EIP-1271 compatibility), and extended with EIP-3009 transfer with authorization (via EIP-712).\n * @author M^0 Labs\n * @dev    The additional interface as defined by EIP-2612: https://eips.ethereum.org/EIPS/eip-2612\n */\ninterface IERC20Extended is IERC20, IERC3009 {\n    /* ============ Custom Errors ============ */\n\n    /**\n     * @notice Revert message when spender's allowance is not sufficient.\n     * @param  spender    Address that may be allowed to operate on tokens without being their owner.\n     * @param  allowance  Amount of tokens a `spender` is allowed to operate with.\n     * @param  needed     Minimum amount required to perform a transfer.\n     */\n    error InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\n\n    /**\n     * @notice Revert message emitted when the transferred amount is insufficient.\n     * @param  amount Amount transferred.\n     */\n    error InsufficientAmount(uint256 amount);\n\n    /**\n     * @notice Revert message emitted when the recipient of a token is invalid.\n     * @param  recipient Address of the invalid recipient.\n     */\n    error InvalidRecipient(address recipient);\n\n    /* ============ Interactive Functions ============ */\n\n    /**\n     * @notice Approves `spender` to spend up to `amount` of the token balance of `owner`, via a signature.\n     * @param  owner    The address of the account who's token balance is being approved to be spent by `spender`.\n     * @param  spender  The address of an account allowed to spend on behalf of `owner`.\n     * @param  value    The amount of the allowance being approved.\n     * @param  deadline The last block number where the signature is still valid.\n     * @param  v        An ECDSA secp256k1 signature parameter (EIP-2612 via EIP-712).\n     * @param  r        An ECDSA secp256k1 signature parameter (EIP-2612 via EIP-712).\n     * @param  s        An ECDSA secp256k1 signature parameter (EIP-2612 via EIP-712).\n     */\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    /**\n     * @notice Approves `spender` to spend up to `amount` of the token balance of `owner`, via a signature.\n     * @param  owner     The address of the account who's token balance is being approved to be spent by `spender`.\n     * @param  spender   The address of an account allowed to spend on behalf of `owner`.\n     * @param  value     The amount of the allowance being approved.\n     * @param  deadline  The last block number where the signature is still valid.\n     * @param  signature An arbitrary signature (EIP-712).\n     */\n    function permit(address owner, address spender, uint256 value, uint256 deadline, bytes memory signature) external;\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @notice Returns the EIP712 typehash used in the encoding of the digest for the permit function.\n    function PERMIT_TYPEHASH() external view returns (bytes32);\n}\n"
      },
      "lib/ttg/src/abstract/interfaces/IERC5805.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\nimport { IStatefulERC712 } from \"../../../lib/common/src/interfaces/IStatefulERC712.sol\";\n\nimport { IERC6372 } from \"./IERC6372.sol\";\n\n/**\n * @title  Voting with voting weight tracking and delegation support.\n * @author M^0 Labs\n * @dev    The interface as defined by EIP-5805: https://eips.ethereum.org/EIPS/eip-5805\n */\ninterface IERC5805 is IStatefulERC712, IERC6372 {\n    /* ============ Events ============ */\n\n    /**\n     * @notice Emitted when `delegator` changes its voting power delegation from `fromDelegatee` to `toDelegatee`.\n     * @param  delegator     The address of the account changing its voting power delegation.\n     * @param  fromDelegatee The previous account the voting power of `delegator` was delegated to.\n     * @param  toDelegatee   The new account the voting power of `delegator` is delegated to.\n     */\n    event DelegateChanged(address indexed delegator, address indexed fromDelegatee, address indexed toDelegatee);\n\n    /**\n     * @notice Emitted when the available voting power of `delegatee` changes from `previousBalance` to `newBalance`.\n     * @param  delegatee       The address of the account whose voting power is changed.\n     * @param  previousBalance The previous voting power of `delegatee`.\n     * @param  newBalance      The new voting power of `delegatee`.\n     */\n    event DelegateVotesChanged(address indexed delegatee, uint256 previousBalance, uint256 newBalance);\n\n    /* ============ Custom Errors ============ */\n\n    /**\n     * @notice Revert message when a query for past values is for a timepoint greater or equal to the current clock.\n     * @param  timepoint The timepoint being queried.\n     * @param  clock     The current timepoint.\n     */\n    error NotPastTimepoint(uint48 timepoint, uint48 clock);\n\n    /* ============ Interactive Functions ============ */\n\n    /**\n     * @notice Allows a calling account to change its voting power delegation to `delegatee`.\n     * @param  delegatee The address of the account the caller's voting power will be delegated to.\n     */\n    function delegate(address delegatee) external;\n\n    /**\n     * @notice Changes the signing account's voting power delegation to `delegatee`.\n     * @param  delegatee The address of the account the signing account's voting power will be delegated to.\n     * @param  nonce     The nonce of the account delegating.\n     * @param  expiry    The timestamp until which the signature is still valid.\n     * @param  v         A signature parameter.\n     * @param  r         A signature parameter.\n     * @param  s         A signature parameter.\n     */\n    function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external;\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @notice Returns the EIP712 typehash used in the encoding of the digest for the delegateBySig function.\n    function DELEGATION_TYPEHASH() external view returns (bytes32);\n\n    /**\n     * @notice Returns the delegatee the voting power of `account` is delegated to.\n     * @param  account The address of the account that can delegate its voting power.\n     * @return The address of the account the voting power of `account` will be delegated to.\n     */\n    function delegates(address account) external view returns (address);\n\n    /**\n     * @notice Returns the total voting power of `account` at a past clock value `timepoint`.\n     * @param  account   The address of some account.\n     * @param  timepoint The point in time, according to the clock mode the contract is operating on.\n     * @return The total voting power of `account` at clock value `timepoint`.\n     */\n    function getPastVotes(address account, uint256 timepoint) external view returns (uint256);\n\n    /**\n     * @notice Returns the total voting power of `account`.\n     * @param  account The address of some account.\n     * @return The total voting power of `account`.\n     */\n    function getVotes(address account) external view returns (uint256);\n}\n"
      },
      "lib/ttg/src/abstract/interfaces/IEpochBasedInflationaryVoteToken.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\nimport { IEpochBasedVoteToken } from \"./IEpochBasedVoteToken.sol\";\n\n/**\n * @title  Extension for an EpochBasedVoteToken token that allows for inflating tokens and voting power.\n * @author M^0 Labs\n */\ninterface IEpochBasedInflationaryVoteToken is IEpochBasedVoteToken {\n    /* ============ Events ============ */\n\n    /**\n     * @notice Emitted when `account` is manually synced.\n     * @param  account The address of an account that is synced.\n     */\n    event Sync(address indexed account);\n\n    /* ============ Custom Errors ============ */\n\n    /// @notice Revert message when trying to mark an account as participated in an epoch where it already participated.\n    error AlreadyParticipated();\n\n    /**\n     * @notice Revert message when the proposed epoch is larger than the current epoch.\n     * @param  currentEpoch The current epoch clock value.\n     * @param  epoch        The handled epoch clock value.\n     */\n    error FutureEpoch(uint16 currentEpoch, uint16 epoch);\n\n    /// @notice Revert message when trying to construct contact with inflation above 100%.\n    error InflationTooHigh();\n\n    /// @notice Revert message when trying to perform an action not allowed outside of designated voting epochs.\n    error NotVoteEpoch();\n\n    /// @notice Revert message when trying to perform an action not allowed during designated voting epochs.\n    error VoteEpoch();\n\n    /* ============ Interactive Functions ============ */\n\n    /**\n     * @dev   Syncs `account` so that its balance Snap array in storage, reflects their unrealized inflation.\n     * @param account The address of the account to sync.\n     */\n    function sync(address account) external;\n\n    /* ============ View/Pure Functions ============ */\n\n    /**\n     * @notice Returns whether `delegatee` has participated in voting during clock value `epoch`.\n     * @param  delegatee The address of a delegatee with voting power.\n     * @param  epoch     The epoch number as a clock value.\n     * @return Whether `delegatee` has participated in voting during `epoch`.\n     */\n    function hasParticipatedAt(address delegatee, uint256 epoch) external view returns (bool);\n\n    /// @notice Returns the participation inflation rate used to inflate tokens for participation.\n    function participationInflation() external view returns (uint16);\n\n    /// @notice Returns 100% in basis point, to be used to correctly ascertain the participation inflation rate.\n    function ONE() external pure returns (uint16);\n}\n"
      },
      "lib/ttg/src/abstract/EpochBasedVoteToken.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\nimport { IERC20 } from \"../../lib/common/src/interfaces/IERC20.sol\";\n\nimport { ERC20Extended } from \"../../lib/common/src/ERC20Extended.sol\";\nimport { UIntMath } from \"../../lib/common/src/libs/UIntMath.sol\";\n\nimport { PureEpochs } from \"../libs/PureEpochs.sol\";\n\nimport { IERC5805 } from \"./interfaces/IERC5805.sol\";\nimport { IERC6372 } from \"./interfaces/IERC6372.sol\";\nimport { IEpochBasedVoteToken } from \"./interfaces/IEpochBasedVoteToken.sol\";\n\nimport { ERC5805 } from \"./ERC5805.sol\";\n\n/**\n * @title  Extension for an ERC5805 token that uses epochs as its clock mode and delegation via IERC1271.\n * @author M^0 Labs\n */\nabstract contract EpochBasedVoteToken is IEpochBasedVoteToken, ERC5805, ERC20Extended {\n    /* ============ Structs ============ */\n\n    /// @dev A 32-byte struct containing a starting epoch and an address that is valid until the next AccountSnap.\n    struct AccountSnap {\n        uint16 startingEpoch;\n        address account;\n    }\n\n    /// @dev A 32-byte struct containing a starting epoch and an amount that is valid until the next AmountSnap.\n    struct AmountSnap {\n        uint16 startingEpoch;\n        uint240 amount;\n    }\n\n    /* ============ Variables ============ */\n\n    /// @dev Store the total supply per epoch.\n    AmountSnap[] internal _totalSupplies;\n\n    /// @dev Store the balance per epoch per account.\n    mapping(address account => AmountSnap[] balanceSnaps) internal _balances;\n\n    /// @dev Store the delegatee per epoch per account.\n    mapping(address account => AccountSnap[] delegateeSnaps) internal _delegatees;\n\n    /// @dev Store the voting power per epoch per delegatee.\n    mapping(address delegatee => AmountSnap[] votingPowerSnaps) internal _votingPowers;\n\n    /* ============ Constructor ============ */\n\n    /**\n     * @notice Constructs a new EpochBasedVoteToken contract.\n     * @param  name_     The name of the token.\n     * @param  symbol_   The symbol of the token.\n     * @param  decimals_ The decimals of the token.\n     */\n    constructor(string memory name_, string memory symbol_, uint8 decimals_) ERC20Extended(name_, symbol_, decimals_) {}\n\n    /* ============ Interactive Functions ============ */\n\n    /// @inheritdoc IEpochBasedVoteToken\n    function delegateBySig(\n        address account_,\n        address delegatee_,\n        uint256 nonce_,\n        uint256 expiry_,\n        bytes memory signature_\n    ) external {\n        _revertIfExpired(expiry_);\n        _revertIfInvalidSignature(account_, _getDelegationDigest(delegatee_, nonce_, expiry_), signature_);\n        _checkAndIncrementNonce(account_, nonce_);\n        _delegate(account_, delegatee_);\n    }\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @inheritdoc IERC20\n    function balanceOf(address account_) external view returns (uint256) {\n        return _getBalance(account_, _clock());\n    }\n\n    /// @inheritdoc IEpochBasedVoteToken\n    function getDelegationDigest(address delegatee_, uint256 nonce_, uint256 expiry_) external view returns (bytes32) {\n        return _getDelegationDigest(delegatee_, nonce_, expiry_);\n    }\n\n    /// @inheritdoc IEpochBasedVoteToken\n    function pastBalanceOf(address account_, uint256 epoch_) external view returns (uint256) {\n        uint16 safeEpoch_ = UIntMath.safe16(epoch_);\n\n        _revertIfNotPastTimepoint(safeEpoch_); // Per EIP-5805, should revert if `epoch_` is not in the past.\n\n        return _getBalance(account_, safeEpoch_);\n    }\n\n    /// @inheritdoc IERC6372\n    function clock() external view returns (uint48 clock_) {\n        return _clock();\n    }\n\n    /// @inheritdoc IERC5805\n    function delegates(address account_) external view returns (address) {\n        return _getDelegatee(account_, _clock());\n    }\n\n    /// @inheritdoc IEpochBasedVoteToken\n    function pastDelegates(address account_, uint256 epoch_) external view returns (address) {\n        uint16 safeEpoch_ = UIntMath.safe16(epoch_);\n\n        _revertIfNotPastTimepoint(safeEpoch_); // Per EIP-5805, should revert if `epoch_` is not in the past.\n\n        return _getDelegatee(account_, safeEpoch_);\n    }\n\n    /// @inheritdoc IERC5805\n    function getVotes(address account_) external view returns (uint256) {\n        return _getVotes(account_, _clock());\n    }\n\n    /// @inheritdoc IERC5805\n    function getPastVotes(address account_, uint256 epoch_) external view returns (uint256) {\n        uint16 safeEpoch_ = UIntMath.safe16(epoch_);\n\n        _revertIfNotPastTimepoint(safeEpoch_); // Per EIP-5805, should revert if `epoch_` is not in the past.\n\n        return _getVotes(account_, safeEpoch_);\n    }\n\n    /// @inheritdoc IERC20\n    function totalSupply() external view returns (uint256) {\n        return _getTotalSupply(_clock());\n    }\n\n    /// @inheritdoc IEpochBasedVoteToken\n    function pastTotalSupply(uint256 epoch_) external view returns (uint256) {\n        uint16 safeEpoch_ = UIntMath.safe16(epoch_);\n\n        _revertIfNotPastTimepoint(safeEpoch_); // Per EIP-5805, should revert if `epoch_` is not in the past.\n\n        return _getTotalSupply(safeEpoch_);\n    }\n\n    /// @inheritdoc IERC6372\n    function CLOCK_MODE() external pure returns (string memory clockMode_) {\n        return PureEpochs.clockMode();\n    }\n\n    /* ============ Internal Interactive Functions ============ */\n\n    /**\n     * @dev   Add `amount_` to the balance of `account_`, using unchecked math.\n     * @param account_ The address of the account to add the balance to.\n     * @param amount_  The amount to add to the balance.\n     */\n    function _addBalance(address account_, uint240 amount_) internal {\n        _updateBalance(account_, _addUnchecked, amount_); // Update balance using `_addUnchecked` operation.\n    }\n\n    /**\n     * @dev   Add `amount_` to the total supply, using checked math.\n     * @param amount_ The amount to add to the total supply.\n     */\n    function _addTotalSupply(uint240 amount_) internal {\n        _update(_totalSupplies, _add, amount_); // Update total supply using `_add` operation.\n    }\n\n    /**\n     * @dev   Add `amount_` to the voting power of `account_`, using unchecked math.\n     * @param account_ The address of the account to add the voting power to.\n     * @param amount_  The amount to add to the voting power.\n     */\n    function _addVotingPower(address account_, uint240 amount_) internal {\n        _updateVotingPower(account_, _addUnchecked, amount_); // Update voting power using `_addUnchecked` operation.\n    }\n\n    /**\n     * @dev   Set a new delegatee for `delegator_`.\n     * @param delegator_    The address of the account delegating voting power.\n     * @param newDelegatee_ The address of the account receiving voting power.\n     */\n    function _delegate(address delegator_, address newDelegatee_) internal virtual override {\n        // `delegatee_` will be `delegator_` (the default) if `delegatee_` was passed in as `address(0)`.\n        address newNonZeroDelegatee_ = _getDefaultIfZero(newDelegatee_, delegator_);\n        address oldDelegatee_ = _setDelegatee(delegator_, newNonZeroDelegatee_);\n        uint240 votingPower_ = _getBalance(delegator_, _clock());\n\n        if (votingPower_ == 0) return;\n\n        _removeVotingPower(oldDelegatee_, votingPower_);\n        _addVotingPower(newNonZeroDelegatee_, votingPower_);\n    }\n\n    /**\n     * @dev   Mint `amount_` tokens to `recipient_`.\n     * @param recipient_ The address of the account to mint tokens to.\n     * @param amount_    The amount of tokens to mint.\n     */\n    function _mint(address recipient_, uint256 amount_) internal virtual {\n        _revertIfInvalidRecipient(recipient_);\n\n        if (amount_ == 0) revert InsufficientAmount(amount_);\n\n        emit Transfer(address(0), recipient_, amount_);\n\n        uint240 safeAmount_ = UIntMath.safe240(amount_);\n\n        _addTotalSupply(safeAmount_); // Will revert on overflow.\n        _addBalance(recipient_, safeAmount_);\n        _addVotingPower(_getDelegatee(recipient_, _clock()), safeAmount_);\n    }\n\n    /**\n     * @dev   Subtract `amount_` from the balance of `account_`, using checked math.\n     * @param account_ The address of the account to subtract the balance from.\n     * @param amount_  The amount to subtract from the balance.\n     */\n    function _removeBalance(address account_, uint240 amount_) internal {\n        _updateBalance(account_, _sub, amount_); // Update balance using `_sub` operation.\n    }\n\n    /**\n     * @dev   Subtract `amount_` of voting power from the balance of `account_`, using checked math.\n     * @param account_ The address of the account to subtract the voting power from.\n     * @param amount_  The amount of voting power to subtract.\n     */\n    function _removeVotingPower(address account_, uint240 amount_) internal {\n        _updateVotingPower(account_, _sub, amount_); // Update voting power using `_sub` operation.\n    }\n\n    /**\n     * @dev    Set a new delegatee for `delegator_`.\n     * @param  delegator_    The address of the account delegating voting power.\n     * @param  delegatee_    The address of the account receiving voting power.\n     * @return oldDelegatee_ The address of the previous delegatee of `delegator_`.\n     */\n    function _setDelegatee(address delegator_, address delegatee_) internal returns (address oldDelegatee_) {\n        uint16 currentEpoch_ = _clock();\n        AccountSnap[] storage delegateeSnaps_ = _delegatees[delegator_];\n        uint256 length_ = delegateeSnaps_.length;\n\n        // If this will be the first AccountSnap, we can just push it onto the empty array.\n        if (length_ == 0) {\n            delegateeSnaps_.push(AccountSnap(currentEpoch_, delegatee_));\n\n            emit DelegateChanged(delegator_, delegator_, delegatee_);\n\n            return delegator_; // In this case, delegatee has always been the `delegator_` itself.\n        }\n\n        unchecked {\n            --length_;\n        }\n\n        AccountSnap storage latestDelegateeSnap_ = _unsafeAccess(delegateeSnaps_, length_);\n\n        oldDelegatee_ = latestDelegateeSnap_.account;\n\n        emit DelegateChanged(delegator_, oldDelegatee_, delegatee_);\n\n        // If the current epoch is greater than the last AccountSnap's startingEpoch, we can push a new\n        // AccountSnap onto the array, else we can just update the last AccountSnap's account.\n        if (currentEpoch_ > latestDelegateeSnap_.startingEpoch) {\n            delegateeSnaps_.push(AccountSnap(currentEpoch_, delegatee_));\n        } else {\n            latestDelegateeSnap_.account = delegatee_;\n        }\n    }\n\n    /**\n     * @dev   Transfer `amount_` tokens from `sender_` to `recipient_`.\n     * @param sender_    The address of the account to transfer tokens from.\n     * @param recipient_ The address of the account to transfer tokens to.\n     * @param amount_    The amount of tokens to transfer.\n     */\n    function _transfer(address sender_, address recipient_, uint256 amount_) internal virtual override {\n        _revertIfInvalidRecipient(recipient_);\n\n        emit Transfer(sender_, recipient_, amount_);\n\n        uint240 safeAmount_ = UIntMath.safe240(amount_);\n        uint16 currentEpoch_ = _clock();\n\n        _removeBalance(sender_, safeAmount_); // Will revert on underflow.\n        _removeVotingPower(_getDelegatee(sender_, currentEpoch_), safeAmount_); // Will revert on underflow.\n        _addBalance(recipient_, safeAmount_);\n        _addVotingPower(_getDelegatee(recipient_, currentEpoch_), safeAmount_);\n    }\n\n    /**\n     * @dev    Update a storage AmountSnap by `amount_` given `operation_`.\n     * @param  amountSnaps_ The storage pointer to an AmountSnap array to update.\n     * @param  operation_   The operation to perform on the old and new amounts.\n     * @param  amount_      The amount to update the Snap by.\n     * @return oldAmount_   The previous latest amount of the Snap array.\n     * @return newAmount_   The new latest amount of the Snap array.\n     */\n    function _update(\n        AmountSnap[] storage amountSnaps_,\n        function(uint240, uint240) internal pure returns (uint240) operation_,\n        uint240 amount_\n    ) internal returns (uint240 oldAmount_, uint240 newAmount_) {\n        uint16 currentEpoch_ = _clock();\n        uint256 length_ = amountSnaps_.length;\n\n        // If this will be the first AmountSnap, we can just push it onto the empty array.\n        if (length_ == 0) {\n            // NOTE: `operation_(0, amount_)` is necessary for almost all operations other than setting or adding.\n            amountSnaps_.push(AmountSnap(currentEpoch_, operation_(0, amount_)));\n\n            return (0, amount_); // In this case, the old amount was 0.\n        }\n\n        unchecked {\n            --length_;\n        }\n\n        AmountSnap storage lastAmountSnap_ = _unsafeAccess(amountSnaps_, length_);\n        newAmount_ = operation_(oldAmount_ = lastAmountSnap_.amount, amount_);\n\n        // If the current epoch is greater than the last AmountSnap's startingEpoch, we can push a new\n        // AmountSnap onto the array, else we can just update the last AmountSnap's amount.\n        if (currentEpoch_ > lastAmountSnap_.startingEpoch) {\n            amountSnaps_.push(AmountSnap(currentEpoch_, newAmount_));\n        } else {\n            lastAmountSnap_.amount = newAmount_;\n        }\n    }\n\n    /**\n     * @dev   Update the balance of `account_` by `amount_` given `operation_`.\n     * @param account_   The address of the account to update the balance of.\n     * @param operation_ The operation to perform on the old and new amounts.\n     * @param amount_    The amount to update the balance by.\n     */\n    function _updateBalance(\n        address account_,\n        function(uint240, uint240) internal pure returns (uint240) operation_,\n        uint240 amount_\n    ) internal {\n        _update(_balances[account_], operation_, amount_);\n    }\n\n    /**\n     * @dev   Update the voting power of `delegatee_` by `amount_` given `operation_`.\n     * @param delegatee_ The address of the account to update the voting power of.\n     * @param operation_ The operation to perform on the old and new amounts.\n     * @param amount_    The amount to update the voting power by.\n     */\n    function _updateVotingPower(\n        address delegatee_,\n        function(uint240, uint240) internal pure returns (uint240) operation_,\n        uint240 amount_\n    ) internal {\n        (uint240 oldAmount_, uint240 newAmount_) = _update(_votingPowers[delegatee_], operation_, amount_);\n\n        emit DelegateVotesChanged(delegatee_, oldAmount_, newAmount_);\n    }\n\n    /* ============ Internal View/Pure Functions ============ */\n\n    /**\n     * @dev    Returns the current timepoint according to the mode the contract is operating on.\n     * @return Current timepoint.\n     */\n    function _clock() internal view returns (uint16) {\n        return PureEpochs.currentEpoch();\n    }\n\n    /**\n     * @dev    Get the balance of `account_` at `epoch_`.\n     * @param  account_ The address of the account to get the balance of.\n     * @param  epoch_   The epoch to get the balance at.\n     * @return The balance of `account_` at `epoch_`.\n     */\n    function _getBalance(address account_, uint16 epoch_) internal view virtual returns (uint240) {\n        return _getValueAt(_balances[account_], epoch_);\n    }\n\n    /**\n     * @dev    Get the delegatee of `account_` at `epoch_`.\n     * @dev    The delegatee is the account itself (the default) if no retrieved delegatee was found.\n     * @param  account_ The address of the account to get the delegatee of.\n     * @param  epoch_   The epoch to get the delegatee at.\n     * @return The delegatee of `account_` at `epoch_`.\n     */\n    function _getDelegatee(address account_, uint256 epoch_) internal view virtual returns (address) {\n        if (epoch_ == 0) revert EpochZero();\n\n        AccountSnap[] storage delegateeSnaps_ = _delegatees[account_];\n\n        uint256 index_ = delegateeSnaps_.length; // NOTE: `index_` starts out as length, and would be out of bounds.\n\n        // Keep going back until we find the first snap with a startingEpoch less than or equal to `epoch_`. This snap\n        // has the account applicable to `epoch_`. If we exhaust the array, then the delegatee is an account itself.\n        while (index_ > 0) {\n            unchecked {\n                AccountSnap storage accountSnap_ = _unsafeAccess(delegateeSnaps_, --index_);\n\n                if (accountSnap_.startingEpoch <= epoch_) return accountSnap_.account;\n            }\n        }\n\n        return account_;\n    }\n\n    /**\n     * @dev    Get the total supply at `epoch_`.\n     * @param  epoch_ The epoch to get the total supply at.\n     * @return The total supply at `epoch_`.\n     */\n    function _getTotalSupply(uint16 epoch_) internal view virtual returns (uint240) {\n        return _getValueAt(_totalSupplies, epoch_);\n    }\n\n    /**\n     * @dev    Get the value of an AmountSnap array at a given epoch.\n     * @param  amountSnaps_ The array of AmountSnaps to get the value of.\n     * @param  epoch_       The epoch to get the value at.\n     * @return The value of the AmountSnap array at `epoch_`.\n     */\n    function _getValueAt(AmountSnap[] storage amountSnaps_, uint16 epoch_) internal view returns (uint240) {\n        if (epoch_ == 0) revert EpochZero();\n\n        uint256 index_ = amountSnaps_.length; // NOTE: `index_` starts out as length, and would be out of bounds.\n\n        // Keep going back until we find the first snap with a startingEpoch less than or equal to `epoch_`. This snap\n        // has the amount applicable to `epoch_`. If we exhaust the array, then the amount is 0.\n        while (index_ > 0) {\n            unchecked {\n                AmountSnap storage amountSnap_ = _unsafeAccess(amountSnaps_, --index_);\n\n                if (amountSnap_.startingEpoch <= epoch_) return amountSnap_.amount;\n            }\n        }\n\n        return 0;\n    }\n\n    /**\n     * @dev    The votes of `account_` at `epoch_`.\n     * @param  account_ The address of the account to get the votes of.\n     * @param  epoch_   The epoch to get the votes at.\n     * @return The votes of `account_` at `epoch_`.\n     */\n    function _getVotes(address account_, uint16 epoch_) internal view virtual returns (uint240) {\n        return _getValueAt(_votingPowers[account_], epoch_);\n    }\n\n    /**\n     * @dev   Revert if `epoch_` is not in the past.\n     * @param epoch_ The epoch to check.\n     */\n    function _revertIfNotPastTimepoint(uint16 epoch_) internal view {\n        uint16 currentEpoch_ = _clock();\n\n        if (epoch_ >= currentEpoch_) revert NotPastTimepoint(epoch_, currentEpoch_);\n    }\n\n    /**\n     * @dev   Reverts if the recipient of a `mint` or `transfer` is address(0).\n     * @param recipient_ Address of the recipient to check.\n     */\n    function _revertIfInvalidRecipient(address recipient_) internal pure {\n        if (recipient_ == address(0)) revert InvalidRecipient(recipient_);\n    }\n\n    /**\n     * @dev    Add `b_` to `a_`, using checked math.\n     * @param  a_ The amount to add to.\n     * @param  b_ The amount to add.\n     * @return The sum of `a_` and `b_`.\n     */\n    function _add(uint240 a_, uint240 b_) internal pure returns (uint240) {\n        return a_ + b_;\n    }\n\n    /**\n     * @dev    Add `b_` to `a_`, using unchecked math.\n     * @param  a_ The amount to add to.\n     * @param  b_ The amount to add.\n     * @return The sum of `a_` and `b_`.\n     */\n    function _addUnchecked(uint240 a_, uint240 b_) internal pure returns (uint240) {\n        unchecked {\n            return a_ + b_;\n        }\n    }\n\n    /**\n     * @dev    Return `default_` if `input_` is equal to address(0), else return `input_`.\n     * @param  input_   The input address.\n     * @param  default_ The default address.\n     * @return The input address if not equal to the zero address, else the default address.\n     */\n    function _getDefaultIfZero(address input_, address default_) internal pure returns (address) {\n        return input_ == address(0) ? default_ : input_;\n    }\n\n    /**\n     * @dev    Subtract `b_` from `a_`, using checked math.\n     * @param  a_ The amount to subtract from.\n     * @param  b_ The amount to subtract.\n     * @return The difference of `a_` and `b_`.\n     */\n    function _sub(uint240 a_, uint240 b_) internal pure returns (uint240) {\n        return a_ - b_;\n    }\n\n    /**\n     * @dev    Returns the AmountSnap in an array at a given index without doing bounds checking.\n     * @param  amountSnaps_ The array of AmountSnaps to parse.\n     * @param  index_       The index of the AmountSnap to return.\n     * @return amountSnap_  The AmountSnap at `index_`.\n     */\n    function _unsafeAccess(\n        AmountSnap[] storage amountSnaps_,\n        uint256 index_\n    ) internal pure returns (AmountSnap storage amountSnap_) {\n        assembly {\n            mstore(0, amountSnaps_.slot)\n            amountSnap_.slot := add(keccak256(0, 0x20), index_)\n        }\n    }\n\n    /**\n     * @dev    Returns the AccountSnap in an array at a given index without doing bounds checking.\n     * @param  accountSnaps_ The array of AccountSnaps to parse.\n     * @param  index_        The index of the AccountSnap to return.\n     * @return accountSnap_  The AccountSnap at `index_`.\n     */\n    function _unsafeAccess(\n        AccountSnap[] storage accountSnaps_,\n        uint256 index_\n    ) internal pure returns (AccountSnap storage accountSnap_) {\n        assembly {\n            mstore(0, accountSnaps_.slot)\n            accountSnap_.slot := add(keccak256(0, 0x20), index_)\n        }\n    }\n}\n"
      },
      "lib/ttg/lib/common/src/interfaces/IERC20.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\n/**\n * @title  ERC20 Token Standard.\n * @author M^0 Labs\n * @dev    The interface as defined by EIP-20: https://eips.ethereum.org/EIPS/eip-20\n */\ninterface IERC20 {\n    /* ============ Events ============ */\n\n    /**\n     * @notice Emitted when `spender` has been approved for `amount` of the token balance of `account`.\n     * @param  account The address of the account.\n     * @param  spender The address of the spender being approved for the allowance.\n     * @param  amount  The amount of the allowance being approved.\n     */\n    event Approval(address indexed account, address indexed spender, uint256 amount);\n\n    /**\n     * @notice Emitted when `amount` tokens is transferred from `sender` to `recipient`.\n     * @param  sender    The address of the sender who's token balance is decremented.\n     * @param  recipient The address of the recipient who's token balance is incremented.\n     * @param  amount    The amount of tokens being transferred.\n     */\n    event Transfer(address indexed sender, address indexed recipient, uint256 amount);\n\n    /* ============ Interactive Functions ============ */\n\n    /**\n     * @notice Allows a calling account to approve `spender` to spend up to `amount` of its token balance.\n     * @dev    MUST emit an `Approval` event.\n     * @param  spender The address of the account being allowed to spend up to the allowed amount.\n     * @param  amount  The amount of the allowance being approved.\n     * @return Whether or not the approval was successful.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @notice Allows a calling account to transfer `amount` tokens to `recipient`.\n     * @param  recipient The address of the recipient who's token balance will be incremented.\n     * @param  amount    The amount of tokens being transferred.\n     * @return Whether or not the transfer was successful.\n     */\n    function transfer(address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @notice Allows a calling account to transfer `amount` tokens from `sender`, with allowance, to a `recipient`.\n     * @param  sender    The address of the sender who's token balance will be decremented.\n     * @param  recipient The address of the recipient who's token balance will be incremented.\n     * @param  amount    The amount of tokens being transferred.\n     * @return Whether or not the transfer was successful.\n     */\n    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n    /* ============ View/Pure Functions ============ */\n\n    /**\n     * @notice Returns the allowance `spender` is allowed to spend on behalf of `account`.\n     * @param  account The address of the account who's token balance `spender` is allowed to spend.\n     * @param  spender The address of an account allowed to spend on behalf of `account`.\n     * @return The amount `spender` can spend on behalf of `account`.\n     */\n    function allowance(address account, address spender) external view returns (uint256);\n\n    /**\n     * @notice Returns the token balance of `account`.\n     * @param  account The address of some account.\n     * @return The token balance of `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /// @notice Returns the number of decimals UIs should assume all amounts have.\n    function decimals() external view returns (uint8);\n\n    /// @notice Returns the name of the contract/token.\n    function name() external view returns (string memory);\n\n    /// @notice Returns the symbol of the token.\n    function symbol() external view returns (string memory);\n\n    /// @notice Returns the current total supply of the token.\n    function totalSupply() external view returns (uint256);\n}\n"
      },
      "lib/ttg/lib/common/src/interfaces/IERC3009.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\nimport { IStatefulERC712 } from \"./IStatefulERC712.sol\";\n\n/**\n * @title  Transfer via signed authorization following EIP-3009 standard.\n * @author M^0 Labs\n * @dev    The interface as defined by EIP-3009: https://eips.ethereum.org/EIPS/eip-3009\n */\ninterface IERC3009 is IStatefulERC712 {\n    /* ============ Events ============ */\n\n    /**\n     * @notice Emitted when an authorization has been canceled.\n     * @param  authorizer Authorizer's address.\n     * @param  nonce      Nonce of the canceled authorization.\n     */\n    event AuthorizationCanceled(address indexed authorizer, bytes32 indexed nonce);\n\n    /**\n     * @notice Emitted when an authorization has been used.\n     * @param  authorizer Authorizer's address.\n     * @param  nonce      Nonce of the used authorization.\n     */\n    event AuthorizationUsed(address indexed authorizer, bytes32 indexed nonce);\n\n    /* ============ Custom Errors ============ */\n\n    /**\n     * @notice Emitted when an authorization has already been used.\n     * @param  authorizer Authorizer's address.\n     * @param  nonce      Nonce of the used authorization.\n     */\n    error AuthorizationAlreadyUsed(address authorizer, bytes32 nonce);\n\n    /**\n     * @notice Emitted when an authorization is expired.\n     * @param  timestamp   Timestamp at which the transaction was submitted.\n     * @param  validBefore Timestamp before which the authorization would have been valid.\n     */\n    error AuthorizationExpired(uint256 timestamp, uint256 validBefore);\n\n    /**\n     * @notice Emitted when an authorization is not yet valid.\n     * @param  timestamp  Timestamp at which the transaction was submitted.\n     * @param  validAfter Timestamp after which the authorization will be valid.\n     */\n    error AuthorizationNotYetValid(uint256 timestamp, uint256 validAfter);\n\n    /**\n     * @notice Emitted when the caller of `receiveWithAuthorization` is not the payee.\n     * @param  caller Caller's address.\n     * @param  payee  Payee's address.\n     */\n    error CallerMustBePayee(address caller, address payee);\n\n    /* ============ Interactive Functions ============ */\n\n    /**\n     * @notice Execute a transfer with a signed authorization.\n     * @param  from        Payer's address (Authorizer).\n     * @param  to          Payee's address.\n     * @param  value       Amount to be transferred.\n     * @param  validAfter  The time after which this is valid (unix time).\n     * @param  validBefore The time before which this is valid (unix time).\n     * @param  nonce       Unique nonce.\n     * @param  signature   A byte array ECDSA/secp256k1 signature (encoded r, s, v).\n     */\n    function transferWithAuthorization(\n        address from,\n        address to,\n        uint256 value,\n        uint256 validAfter,\n        uint256 validBefore,\n        bytes32 nonce,\n        bytes memory signature\n    ) external;\n\n    /**\n     * @notice Execute a transfer with a signed authorization.\n     * @param  from        Payer's address (Authorizer).\n     * @param  to          Payee's address.\n     * @param  value       Amount to be transferred.\n     * @param  validAfter  The time after which this is valid (unix time).\n     * @param  validBefore The time before which this is valid (unix time).\n     * @param  nonce       Unique nonce.\n     * @param  r           An ECDSA/secp256k1 signature parameter.\n     * @param  vs          An ECDSA/secp256k1 short signature parameter.\n     */\n    function transferWithAuthorization(\n        address from,\n        address to,\n        uint256 value,\n        uint256 validAfter,\n        uint256 validBefore,\n        bytes32 nonce,\n        bytes32 r,\n        bytes32 vs\n    ) external;\n\n    /**\n     * @notice Execute a transfer with a signed authorization.\n     * @param  from        Payer's address (Authorizer).\n     * @param  to          Payee's address.\n     * @param  value       Amount to be transferred.\n     * @param  validAfter  The time after which this is valid (unix time).\n     * @param  validBefore The time before which this is valid (unix time).\n     * @param  nonce       Unique nonce.\n     * @param  v           v of the signature.\n     * @param  r           r of the signature.\n     * @param  s           s of the signature.\n     */\n    function transferWithAuthorization(\n        address from,\n        address to,\n        uint256 value,\n        uint256 validAfter,\n        uint256 validBefore,\n        bytes32 nonce,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    /**\n     * @notice Receive a transfer with a signed authorization from the payer.\n     * @dev    This has an additional check to ensure that the payee's address matches\n     *         the caller of this function to prevent front-running attacks.\n     *         (See security considerations)\n     * @param  from        Payer's address (Authorizer).\n     * @param  to          Payee's address.\n     * @param  value       Amount to be transferred.\n     * @param  validAfter  The time after which this is valid (unix time).\n     * @param  validBefore The time before which this is valid (unix time).\n     * @param  nonce       Unique nonce.\n     * @param  signature   A byte array ECDSA/secp256k1 signature (encoded r, s, v).\n     */\n    function receiveWithAuthorization(\n        address from,\n        address to,\n        uint256 value,\n        uint256 validAfter,\n        uint256 validBefore,\n        bytes32 nonce,\n        bytes memory signature\n    ) external;\n\n    /**\n     * @notice Receive a transfer with a signed authorization from the payer.\n     * @dev    This has an additional check to ensure that the payee's address matches\n     *         the caller of this function to prevent front-running attacks.\n     *         (See security considerations)\n     * @param  from        Payer's address (Authorizer).\n     * @param  to          Payee's address.\n     * @param  value       Amount to be transferred.\n     * @param  validAfter  The time after which this is valid (unix time).\n     * @param  validBefore The time before which this is valid (unix time).\n     * @param  nonce       Unique nonce.\n     * @param  r           An ECDSA/secp256k1 signature parameter.\n     * @param  vs          An ECDSA/secp256k1 short signature parameter.\n     */\n    function receiveWithAuthorization(\n        address from,\n        address to,\n        uint256 value,\n        uint256 validAfter,\n        uint256 validBefore,\n        bytes32 nonce,\n        bytes32 r,\n        bytes32 vs\n    ) external;\n\n    /**\n     * @notice Receive a transfer with a signed authorization from the payer.\n     * @dev    This has an additional check to ensure that the payee's address matches\n     *         the caller of this function to prevent front-running attacks.\n     *         (See security considerations)\n     * @param  from        Payer's address (Authorizer).\n     * @param  to          Payee's address.\n     * @param  value       Amount to be transferred.\n     * @param  validAfter  The time after which this is valid (unix time).\n     * @param  validBefore The time before which this is valid (unix time).\n     * @param  nonce       Unique nonce.\n     * @param  v           v of the signature.\n     * @param  r           r of the signature.\n     * @param  s           s of the signature.\n     */\n    function receiveWithAuthorization(\n        address from,\n        address to,\n        uint256 value,\n        uint256 validAfter,\n        uint256 validBefore,\n        bytes32 nonce,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    /**\n     * @notice Attempt to cancel an authorization.\n     * @param  authorizer Authorizer's address.\n     * @param  nonce      Nonce of the authorization.\n     * @param  signature  A byte array ECDSA/secp256k1 signature (encoded r, s, v).\n     */\n    function cancelAuthorization(address authorizer, bytes32 nonce, bytes memory signature) external;\n\n    /**\n     * @notice Attempt to cancel an authorization.\n     * @param  authorizer Authorizer's address.\n     * @param  nonce      Nonce of the authorization.\n     * @param  r          An ECDSA/secp256k1 signature parameter.\n     * @param  vs         An ECDSA/secp256k1 short signature parameter.\n     */\n    function cancelAuthorization(address authorizer, bytes32 nonce, bytes32 r, bytes32 vs) external;\n\n    /**\n     * @notice Attempt to cancel an authorization.\n     * @param  authorizer Authorizer's address.\n     * @param  nonce      Nonce of the authorization.\n     * @param  v          v of the signature.\n     * @param  r          r of the signature.\n     * @param  s          s of the signature.\n     */\n    function cancelAuthorization(address authorizer, bytes32 nonce, uint8 v, bytes32 r, bytes32 s) external;\n\n    /* ============ View/Pure Functions ============ */\n\n    /**\n     * @notice Returns the state of an authorization.\n     * @dev    Nonces are randomly generated 32-byte data unique to the authorizer's address\n     * @param  authorizer Authorizer's address.\n     * @param  nonce      Nonce of the authorization.\n     * @return True if the nonce is used.\n     */\n    function authorizationState(address authorizer, bytes32 nonce) external view returns (bool);\n\n    /// @notice Returns `transferWithAuthorization` typehash.\n    function TRANSFER_WITH_AUTHORIZATION_TYPEHASH() external view returns (bytes32);\n\n    /// @notice Returns `receiveWithAuthorization` typehash.\n    function RECEIVE_WITH_AUTHORIZATION_TYPEHASH() external view returns (bytes32);\n\n    /// @notice Returns `cancelAuthorization` typehash.\n    function CANCEL_AUTHORIZATION_TYPEHASH() external view returns (bytes32);\n}\n"
      },
      "lib/ttg/lib/common/src/interfaces/IStatefulERC712.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\nimport { IERC712Extended } from \"./IERC712Extended.sol\";\n\n/**\n * @title  Stateful Extension for EIP-712 typed structured data hashing and signing with nonces.\n * @author M^0 Labs\n */\ninterface IStatefulERC712 is IERC712Extended {\n    /* ============ Custom Errors ============ */\n\n    /**\n     * @notice Revert message when a signing account's nonce is not the expected current nonce.\n     * @param  nonce         The nonce used in the signature.\n     * @param  expectedNonce The expected nonce to be used in a signature by the signing account.\n     */\n    error InvalidAccountNonce(uint256 nonce, uint256 expectedNonce);\n\n    /* ============ View/Pure Functions ============ */\n\n    /**\n     * @notice Returns the next nonce to be used in a signature by `account`.\n     * @param  account The address of some account.\n     * @return nonce   The next nonce to be used in a signature by `account`.\n     */\n    function nonces(address account) external view returns (uint256 nonce);\n}\n"
      },
      "lib/ttg/src/abstract/interfaces/IERC6372.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\n/**\n * @title  Contract clock properties.\n * @author M^0 Labs\n * @dev    The interface as defined by EIP-6372: https://eips.ethereum.org/EIPS/eip-6372\n */\ninterface IERC6372 {\n    /// @notice Returns a machine-readable string description of the clock the contract is operating on.\n    function CLOCK_MODE() external view returns (string memory);\n\n    /// @notice Returns the current timepoint according to the mode the contract is operating on.\n    function clock() external view returns (uint48);\n}\n"
      },
      "lib/ttg/lib/common/src/ERC20Extended.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\nimport { IERC20 } from \"./interfaces/IERC20.sol\";\nimport { IERC20Extended } from \"./interfaces/IERC20Extended.sol\";\n\nimport { ERC3009 } from \"./ERC3009.sol\";\n\n/**\n * @title  An ERC20 token extended with EIP-2612 permits for signed approvals (via EIP-712 and with EIP-1271\n *         and EIP-5267 compatibility), and extended with EIP-3009 transfer with authorization (via EIP-712).\n * @author M^0 Labs\n */\nabstract contract ERC20Extended is IERC20Extended, ERC3009 {\n    /* ============ Variables ============ */\n\n    /**\n     * @inheritdoc IERC20Extended\n     * @dev Keeping this constant, despite `permit` parameter name differences, to ensure max EIP-2612 compatibility.\n     *      keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\")\n     */\n    bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n\n    /// @inheritdoc IERC20\n    uint8 public immutable decimals;\n\n    /// @inheritdoc IERC20\n    string public symbol;\n\n    /// @inheritdoc IERC20\n    mapping(address account => mapping(address spender => uint256 allowance)) public allowance;\n\n    /* ============ Constructor ============ */\n\n    /**\n     * @notice Constructs the ERC20Extended contract.\n     * @param  name_     The name of the token.\n     * @param  symbol_   The symbol of the token.\n     * @param  decimals_ The number of decimals the token uses.\n     */\n    constructor(string memory name_, string memory symbol_, uint8 decimals_) ERC3009(name_) {\n        symbol = symbol_;\n        decimals = decimals_;\n    }\n\n    /* ============ Interactive Functions ============ */\n\n    /// @inheritdoc IERC20\n    function approve(address spender_, uint256 amount_) external returns (bool success_) {\n        _approve(msg.sender, spender_, amount_);\n        return true;\n    }\n\n    /// @inheritdoc IERC20Extended\n    function permit(\n        address owner_,\n        address spender_,\n        uint256 value_,\n        uint256 deadline_,\n        uint8 v_,\n        bytes32 r_,\n        bytes32 s_\n    ) external {\n        _revertIfInvalidSignature(owner_, _permitAndGetDigest(owner_, spender_, value_, deadline_), v_, r_, s_);\n    }\n\n    /// @inheritdoc IERC20Extended\n    function permit(\n        address owner_,\n        address spender_,\n        uint256 value_,\n        uint256 deadline_,\n        bytes memory signature_\n    ) external {\n        _revertIfInvalidSignature(owner_, _permitAndGetDigest(owner_, spender_, value_, deadline_), signature_);\n    }\n\n    /// @inheritdoc IERC20\n    function transfer(address recipient_, uint256 amount_) external returns (bool success_) {\n        _transfer(msg.sender, recipient_, amount_);\n        return true;\n    }\n\n    /// @inheritdoc IERC20\n    function transferFrom(address sender_, address recipient_, uint256 amount_) external returns (bool success_) {\n        uint256 spenderAllowance_ = allowance[sender_][msg.sender]; // Cache `spenderAllowance_` to stack.\n\n        if (spenderAllowance_ != type(uint256).max) {\n            if (spenderAllowance_ < amount_) revert InsufficientAllowance(msg.sender, spenderAllowance_, amount_);\n\n            unchecked {\n                _setAllowance(sender_, msg.sender, spenderAllowance_ - amount_);\n            }\n        }\n\n        _transfer(sender_, recipient_, amount_);\n\n        return true;\n    }\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @inheritdoc IERC20\n    function name() external view returns (string memory name_) {\n        return _name;\n    }\n\n    /* ============ Internal Interactive Functions ============ */\n\n    /**\n     * @dev Approve `spender_` to spend `amount_` of tokens from `account_`.\n     * @param  account_ The address approving the allowance.\n     * @param  spender_ The address approved to spend the tokens.\n     * @param  amount_  The amount of tokens being approved for spending.\n     */\n    function _approve(address account_, address spender_, uint256 amount_) internal virtual {\n        _setAllowance(account_, spender_, amount_);\n        emit Approval(account_, spender_, amount_);\n    }\n\n    /**\n     * @dev Set the `amount_` of tokens `spender_` is allowed to spend from `account_`.\n     * @param  account_ The address for which the allowance is set.\n     * @param  spender_ The address allowed to spend the tokens.\n     * @param  amount_  The amount of tokens being allowed for spending.\n     */\n    function _setAllowance(address account_, address spender_, uint256 amount_) internal virtual {\n        allowance[account_][spender_] = amount_;\n    }\n\n    /**\n     * @dev    Performs the approval based on the permit info, validates the deadline, and returns the digest.\n     * @param  owner_    The address of the account approving the allowance.\n     * @param  spender_  The address of the account being allowed to spend the tokens.\n     * @param  amount_   The amount of tokens being approved for spending.\n     * @param  deadline_ The deadline by which the signature must be used.\n     * @return digest_   The EIP-712 digest of the permit.\n     */\n    function _permitAndGetDigest(\n        address owner_,\n        address spender_,\n        uint256 amount_,\n        uint256 deadline_\n    ) internal virtual returns (bytes32 digest_) {\n        _revertIfExpired(deadline_);\n\n        _approve(owner_, spender_, amount_);\n\n        unchecked {\n            // Nonce realistically cannot overflow.\n            return\n                _getDigest(\n                    keccak256(abi.encode(PERMIT_TYPEHASH, owner_, spender_, amount_, nonces[owner_]++, deadline_))\n                );\n        }\n    }\n}\n"
      },
      "lib/ttg/src/abstract/ERC5805.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\nimport { StatefulERC712 } from \"../../lib/common/src/StatefulERC712.sol\";\n\nimport { IERC5805 } from \"./interfaces/IERC5805.sol\";\n\n/**\n * @title  Voting with voting weight tracking and delegation support.\n * @author M^0 Labs\n */\nabstract contract ERC5805 is IERC5805, StatefulERC712 {\n    /* ============ Variables ============ */\n\n    /**\n     * @inheritdoc IERC5805\n     * @dev Keeping this constant, despite `delegateBySig` param name differences, to ensure max EIP-5805 compatibility.\n     *      keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\")\n     */\n    bytes32 public constant DELEGATION_TYPEHASH = 0xe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf;\n\n    /* ============ Interactive Functions ============ */\n\n    /// @inheritdoc IERC5805\n    function delegate(address delegatee_) external {\n        _delegate(msg.sender, delegatee_);\n    }\n\n    /// @inheritdoc IERC5805\n    function delegateBySig(\n        address delegatee_,\n        uint256 nonce_,\n        uint256 expiry_,\n        uint8 v_,\n        bytes32 r_,\n        bytes32 s_\n    ) external {\n        bytes32 digest_ = _getDelegationDigest(delegatee_, nonce_, expiry_);\n        address signer_ = _getSignerAndRevertIfInvalidSignature(digest_, v_, r_, s_);\n\n        _revertIfExpired(expiry_);\n        _checkAndIncrementNonce(signer_, nonce_);\n        _delegate(signer_, delegatee_);\n    }\n\n    /* ============ Internal Interactive Functions ============ */\n\n    /**\n     * @dev   Reverts if a given `nonce_` is reused for `account_`, then increments the nonce in storage.\n     * @param account_ The address of the account the nonce is being verified for.\n     * @param nonce_   The nonce being used by the account.\n     */\n    function _checkAndIncrementNonce(address account_, uint256 nonce_) internal {\n        unchecked {\n            uint256 currentNonce_ = nonces[account_]++; // Nonce realistically cannot overflow.\n\n            if (nonce_ != currentNonce_) revert InvalidAccountNonce(nonce_, currentNonce_);\n        }\n    }\n\n    /**\n     * @dev   Delegate voting power from `delegator_` to `newDelegatee_`.\n     * @param delegator_    The address of the account delegating voting power.\n     * @param newDelegatee_ The address of the account receiving voting power.\n     */\n    function _delegate(address delegator_, address newDelegatee_) internal virtual;\n\n    /* ============ Internal View/Pure Functions ============ */\n\n    /**\n     * @dev    Returns the digest to be signed, via EIP-712, given an internal digest (i.e. hash struct).\n     * @param  delegatee_ The address of the delegatee to delegate to.\n     * @param  nonce_     The nonce of the account delegating.\n     * @param  expiry_    The timestamp until which the signature is still valid.\n     * @return The digest to be signed.\n     */\n    function _getDelegationDigest(address delegatee_, uint256 nonce_, uint256 expiry_) internal view returns (bytes32) {\n        return _getDigest(keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee_, nonce_, expiry_)));\n    }\n}\n"
      },
      "lib/ttg/lib/common/src/interfaces/IERC712Extended.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\nimport { IERC712 } from \"./IERC712.sol\";\n\n/**\n * @title  EIP-712 extended by EIP-5267.\n * @author M^0 Labs\n * @dev    The additional interface as defined by EIP-5267: https://eips.ethereum.org/EIPS/eip-5267\n */\ninterface IERC712Extended is IERC712 {\n    /* ============ Events ============ */\n\n    /// @notice MAY be emitted to signal that the domain could have changed.\n    event EIP712DomainChanged();\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @notice Returns the fields and values that describe the domain separator used by this contract for EIP-712.\n    function eip712Domain()\n        external\n        view\n        returns (\n            bytes1 fields,\n            string memory name,\n            string memory version,\n            uint256 chainId,\n            address verifyingContract,\n            bytes32 salt,\n            uint256[] memory extensions\n        );\n}\n"
      },
      "lib/ttg/lib/common/src/ERC3009.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\nimport { IERC3009 } from \"./interfaces/IERC3009.sol\";\n\nimport { StatefulERC712 } from \"./StatefulERC712.sol\";\n\n/**\n * @title  ERC3009 implementation allowing the transfer of fungible assets via a signed authorization.\n * @author M^0 Labs\n * @dev    Inherits from ERC712 and StatefulERC712.\n */\nabstract contract ERC3009 is IERC3009, StatefulERC712 {\n    /* ============ Variables ============ */\n\n    // solhint-disable-next-line max-line-length\n    /// @dev        keccak256(\"TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)\")\n    /// @inheritdoc IERC3009\n    bytes32 public constant TRANSFER_WITH_AUTHORIZATION_TYPEHASH =\n        0x7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267;\n\n    // solhint-disable-next-line max-line-length\n    /// @dev        keccak256(\"ReceiveWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)\")\n    /// @inheritdoc IERC3009\n    bytes32 public constant RECEIVE_WITH_AUTHORIZATION_TYPEHASH =\n        0xd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de8;\n\n    /**\n     * @inheritdoc IERC3009\n     * @dev        keccak256(\"CancelAuthorization(address authorizer,bytes32 nonce)\")\n     */\n    bytes32 public constant CANCEL_AUTHORIZATION_TYPEHASH =\n        0x158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a1597429;\n\n    /// @inheritdoc IERC3009\n    mapping(address authorizer => mapping(bytes32 nonce => bool isNonceUsed)) public authorizationState;\n\n    /* ============ Constructor ============ */\n\n    /**\n     * @notice Construct the ERC3009 contract.\n     * @param  name_ The name of the contract.\n     */\n    constructor(string memory name_) StatefulERC712(name_) {}\n\n    /* ============ Interactive Functions ============ */\n\n    /// @inheritdoc IERC3009\n    function transferWithAuthorization(\n        address from_,\n        address to_,\n        uint256 value_,\n        uint256 validAfter_,\n        uint256 validBefore_,\n        bytes32 nonce_,\n        bytes memory signature_\n    ) external {\n        _revertIfInvalidSignature(\n            from_,\n            _getTransferWithAuthorizationDigest(from_, to_, value_, validAfter_, validBefore_, nonce_),\n            signature_\n        );\n\n        _transferWithAuthorization(from_, to_, value_, validAfter_, validBefore_, nonce_);\n    }\n\n    /// @inheritdoc IERC3009\n    function transferWithAuthorization(\n        address from_,\n        address to_,\n        uint256 value_,\n        uint256 validAfter_,\n        uint256 validBefore_,\n        bytes32 nonce_,\n        bytes32 r_,\n        bytes32 vs_\n    ) external {\n        _revertIfInvalidSignature(\n            from_,\n            _getTransferWithAuthorizationDigest(from_, to_, value_, validAfter_, validBefore_, nonce_),\n            r_,\n            vs_\n        );\n\n        _transferWithAuthorization(from_, to_, value_, validAfter_, validBefore_, nonce_);\n    }\n\n    /// @inheritdoc IERC3009\n    function transferWithAuthorization(\n        address from_,\n        address to_,\n        uint256 value_,\n        uint256 validAfter_,\n        uint256 validBefore_,\n        bytes32 nonce_,\n        uint8 v_,\n        bytes32 r_,\n        bytes32 s_\n    ) external {\n        _revertIfInvalidSignature(\n            from_,\n            _getTransferWithAuthorizationDigest(from_, to_, value_, validAfter_, validBefore_, nonce_),\n            v_,\n            r_,\n            s_\n        );\n\n        _transferWithAuthorization(from_, to_, value_, validAfter_, validBefore_, nonce_);\n    }\n\n    /// @inheritdoc IERC3009\n    function receiveWithAuthorization(\n        address from_,\n        address to_,\n        uint256 value_,\n        uint256 validAfter_,\n        uint256 validBefore_,\n        bytes32 nonce_,\n        bytes memory signature_\n    ) external {\n        _revertIfInvalidSignature(\n            from_,\n            _getReceiveWithAuthorizationDigest(from_, to_, value_, validAfter_, validBefore_, nonce_),\n            signature_\n        );\n\n        _receiveWithAuthorization(from_, to_, value_, validAfter_, validBefore_, nonce_);\n    }\n\n    /// @inheritdoc IERC3009\n    function receiveWithAuthorization(\n        address from_,\n        address to_,\n        uint256 value_,\n        uint256 validAfter_,\n        uint256 validBefore_,\n        bytes32 nonce_,\n        bytes32 r_,\n        bytes32 vs_\n    ) external {\n        _revertIfInvalidSignature(\n            from_,\n            _getReceiveWithAuthorizationDigest(from_, to_, value_, validAfter_, validBefore_, nonce_),\n            r_,\n            vs_\n        );\n\n        _receiveWithAuthorization(from_, to_, value_, validAfter_, validBefore_, nonce_);\n    }\n\n    /// @inheritdoc IERC3009\n    function receiveWithAuthorization(\n        address from_,\n        address to_,\n        uint256 value_,\n        uint256 validAfter_,\n        uint256 validBefore_,\n        bytes32 nonce_,\n        uint8 v_,\n        bytes32 r_,\n        bytes32 s_\n    ) external {\n        _revertIfInvalidSignature(\n            from_,\n            _getReceiveWithAuthorizationDigest(from_, to_, value_, validAfter_, validBefore_, nonce_),\n            v_,\n            r_,\n            s_\n        );\n\n        _receiveWithAuthorization(from_, to_, value_, validAfter_, validBefore_, nonce_);\n    }\n\n    /// @inheritdoc IERC3009\n    function cancelAuthorization(address authorizer_, bytes32 nonce_, bytes memory signature_) external {\n        _revertIfInvalidSignature(authorizer_, _getCancelAuthorizationDigest(authorizer_, nonce_), signature_);\n        _cancelAuthorization(authorizer_, nonce_);\n    }\n\n    /// @inheritdoc IERC3009\n    function cancelAuthorization(address authorizer_, bytes32 nonce_, bytes32 r_, bytes32 vs_) external {\n        _revertIfInvalidSignature(authorizer_, _getCancelAuthorizationDigest(authorizer_, nonce_), r_, vs_);\n        _cancelAuthorization(authorizer_, nonce_);\n    }\n\n    /// @inheritdoc IERC3009\n    function cancelAuthorization(address authorizer_, bytes32 nonce_, uint8 v_, bytes32 r_, bytes32 s_) external {\n        _revertIfInvalidSignature(authorizer_, _getCancelAuthorizationDigest(authorizer_, nonce_), v_, r_, s_);\n        _cancelAuthorization(authorizer_, nonce_);\n    }\n\n    /* ============ Internal Interactive Functions ============ */\n\n    /**\n     * @dev   Common transfer function used by `transferWithAuthorization` and `_receiveWithAuthorization`.\n     * @param from_        Payer's address (Authorizer).\n     * @param to_          Payee's address.\n     * @param value_       Amount to be transferred.\n     * @param validAfter_  The time after which this is valid (unix time).\n     * @param validBefore_ The time before which this is valid (unix time).\n     * @param nonce_       Unique nonce.\n     */\n    function _transferWithAuthorization(\n        address from_,\n        address to_,\n        uint256 value_,\n        uint256 validAfter_,\n        uint256 validBefore_,\n        bytes32 nonce_\n    ) internal {\n        if (block.timestamp <= validAfter_) revert AuthorizationNotYetValid(block.timestamp, validAfter_);\n        if (block.timestamp >= validBefore_) revert AuthorizationExpired(block.timestamp, validBefore_);\n\n        _revertIfAuthorizationAlreadyUsed(from_, nonce_);\n\n        authorizationState[from_][nonce_] = true;\n\n        emit AuthorizationUsed(from_, nonce_);\n\n        _transfer(from_, to_, value_);\n    }\n\n    /**\n     * @dev   Common receive function used by `receiveWithAuthorization`.\n     * @param from_        Payer's address (Authorizer).\n     * @param to_          Payee's address.\n     * @param value_       Amount to be transferred.\n     * @param validAfter_  The time after which this is valid (unix time).\n     * @param validBefore_ The time before which this is valid (unix time).\n     * @param nonce_       Unique nonce.\n     */\n    function _receiveWithAuthorization(\n        address from_,\n        address to_,\n        uint256 value_,\n        uint256 validAfter_,\n        uint256 validBefore_,\n        bytes32 nonce_\n    ) internal {\n        if (msg.sender != to_) revert CallerMustBePayee(msg.sender, to_);\n\n        _transferWithAuthorization(from_, to_, value_, validAfter_, validBefore_, nonce_);\n    }\n\n    /**\n     * @dev   Common cancel function used by `cancelAuthorization`.\n     * @param authorizer_ Authorizer's address.\n     * @param nonce_      Nonce of the authorization.\n     */\n    function _cancelAuthorization(address authorizer_, bytes32 nonce_) internal {\n        _revertIfAuthorizationAlreadyUsed(authorizer_, nonce_);\n\n        authorizationState[authorizer_][nonce_] = true;\n\n        emit AuthorizationCanceled(authorizer_, nonce_);\n    }\n\n    /**\n     * @dev   Internal ERC20 transfer function that needs to be implemented by the inheriting contract.\n     * @param sender_    The sender's address.\n     * @param recipient_ The recipient's address.\n     * @param amount_    The amount to be transferred.\n     */\n    function _transfer(address sender_, address recipient_, uint256 amount_) internal virtual;\n\n    /* ============ Internal View/Pure Functions ============ */\n\n    /**\n     * @dev    Returns the internal EIP-712 digest of a transferWithAuthorization call.\n     * @param  from_        Payer's address (Authorizer).\n     * @param  to_          Payee's address.\n     * @param  value_       Amount to be transferred.\n     * @param  validAfter_  The time after which this is valid (unix time).\n     * @param  validBefore_ The time before which this is valid (unix time).\n     * @param  nonce_       Unique nonce.\n     * @return The internal EIP-712 digest.\n     */\n    function _getTransferWithAuthorizationDigest(\n        address from_,\n        address to_,\n        uint256 value_,\n        uint256 validAfter_,\n        uint256 validBefore_,\n        bytes32 nonce_\n    ) internal view returns (bytes32) {\n        return\n            _getDigest(\n                keccak256(\n                    abi.encode(\n                        TRANSFER_WITH_AUTHORIZATION_TYPEHASH,\n                        from_,\n                        to_,\n                        value_,\n                        validAfter_,\n                        validBefore_,\n                        nonce_\n                    )\n                )\n            );\n    }\n\n    /**\n     * @dev    Returns the internal EIP-712 digest of a receiveWithAuthorization call.\n     * @param  from_        Payer's address (Authorizer).\n     * @param  to_          Payee's address.\n     * @param  value_       Amount to be transferred.\n     * @param  validAfter_  The time after which this is valid (unix time).\n     * @param  validBefore_ The time before which this is valid (unix time).\n     * @param  nonce_       Unique nonce.\n     * @return The internal EIP-712 digest.\n     */\n    function _getReceiveWithAuthorizationDigest(\n        address from_,\n        address to_,\n        uint256 value_,\n        uint256 validAfter_,\n        uint256 validBefore_,\n        bytes32 nonce_\n    ) internal view returns (bytes32) {\n        return\n            _getDigest(\n                keccak256(\n                    abi.encode(\n                        RECEIVE_WITH_AUTHORIZATION_TYPEHASH,\n                        from_,\n                        to_,\n                        value_,\n                        validAfter_,\n                        validBefore_,\n                        nonce_\n                    )\n                )\n            );\n    }\n\n    /**\n     * @dev    Returns the internal EIP-712 digest of a cancelAuthorization call.\n     * @param  authorizer_ Authorizer's address.\n     * @param  nonce_      Nonce of the authorization.\n     * @return The internal EIP-712 digest.\n     */\n    function _getCancelAuthorizationDigest(address authorizer_, bytes32 nonce_) internal view returns (bytes32) {\n        return _getDigest(keccak256(abi.encode(CANCEL_AUTHORIZATION_TYPEHASH, authorizer_, nonce_)));\n    }\n\n    /**\n     * @dev   Reverts if the authorization is already used.\n     * @param authorizer_ The authorizer's address.\n     * @param nonce_      The nonce of the authorization.\n     */\n    function _revertIfAuthorizationAlreadyUsed(address authorizer_, bytes32 nonce_) internal view {\n        if (authorizationState[authorizer_][nonce_]) revert AuthorizationAlreadyUsed(authorizer_, nonce_);\n    }\n}\n"
      },
      "lib/ttg/lib/common/src/StatefulERC712.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\nimport { IStatefulERC712 } from \"./interfaces/IStatefulERC712.sol\";\n\nimport { ERC712Extended } from \"./ERC712Extended.sol\";\n\n/**\n * @title  Stateful Extension for EIP-712 typed structured data hashing and signing with nonces.\n * @author M^0 Labs\n * @dev    An abstract implementation to satisfy stateful EIP-712 with nonces.\n */\nabstract contract StatefulERC712 is IStatefulERC712, ERC712Extended {\n    /// @inheritdoc IStatefulERC712\n    mapping(address account => uint256 nonce) public nonces; // Nonces for all signatures.\n\n    /**\n     * @notice Construct the StatefulERC712 contract.\n     * @param  name_ The name of the contract.\n     */\n    constructor(string memory name_) ERC712Extended(name_) {}\n}\n"
      },
      "lib/ttg/lib/common/src/interfaces/IERC712.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\n/**\n * @title  Typed structured data hashing and signing via EIP-712.\n * @author M^0 Labs\n * @dev    The interface as defined by EIP-712: https://eips.ethereum.org/EIPS/eip-712\n */\ninterface IERC712 {\n    /* ============ Custom Errors ============ */\n\n    /// @notice Revert message when an invalid signature is detected.\n    error InvalidSignature();\n\n    /// @notice Revert message when a signature with invalid length is detected.\n    error InvalidSignatureLength();\n\n    /// @notice Revert message when the S portion of a signature is invalid.\n    error InvalidSignatureS();\n\n    /// @notice Revert message when the V portion of a signature is invalid.\n    error InvalidSignatureV();\n\n    /**\n     * @notice Revert message when a signature is being used beyond its deadline (i.e. expiry).\n     * @param  deadline  The deadline of the signature.\n     * @param  timestamp The current timestamp.\n     */\n    error SignatureExpired(uint256 deadline, uint256 timestamp);\n\n    /// @notice Revert message when a recovered signer does not match the account being purported to have signed.\n    error SignerMismatch();\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @notice Returns the EIP712 domain separator used in the encoding of a signed digest.\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"
      },
      "lib/ttg/lib/common/src/ERC712Extended.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\nimport { IERC712 } from \"./interfaces/IERC712.sol\";\nimport { IERC712Extended } from \"./interfaces/IERC712Extended.sol\";\n\nimport { SignatureChecker } from \"./libs/SignatureChecker.sol\";\n\n/**\n * @title  Typed structured data hashing and signing via EIP-712, extended by EIP-5267.\n * @author M^0 Labs\n * @dev    An abstract implementation to satisfy EIP-712: https://eips.ethereum.org/EIPS/eip-712\n */\nabstract contract ERC712Extended is IERC712Extended {\n    /* ============ Variables ============ */\n\n    /// @dev keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\")\n    bytes32 internal constant _EIP712_DOMAIN_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n    /// @dev keccak256(\"1\")\n    bytes32 internal constant _EIP712_VERSION_HASH = 0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6;\n\n    /// @dev Initial Chain ID set at deployment.\n    uint256 internal immutable _INITIAL_CHAIN_ID;\n\n    /// @dev Initial EIP-712 domain separator set at deployment.\n    bytes32 internal immutable _INITIAL_DOMAIN_SEPARATOR;\n\n    /// @dev The name of the contract.\n    string internal _name;\n\n    /* ============ Constructor ============ */\n\n    /**\n     * @notice Constructs the EIP-712 domain separator.\n     * @param  name_ The name of the contract.\n     */\n    constructor(string memory name_) {\n        _name = name_;\n\n        _INITIAL_CHAIN_ID = block.chainid;\n        _INITIAL_DOMAIN_SEPARATOR = _getDomainSeparator();\n    }\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @inheritdoc IERC712Extended\n    function eip712Domain()\n        external\n        view\n        virtual\n        returns (\n            bytes1 fields_,\n            string memory name_,\n            string memory version_,\n            uint256 chainId_,\n            address verifyingContract_,\n            bytes32 salt_,\n            uint256[] memory extensions_\n        )\n    {\n        return (\n            hex\"0f\", // 01111\n            _name,\n            \"1\",\n            block.chainid,\n            address(this),\n            bytes32(0),\n            new uint256[](0)\n        );\n    }\n\n    /// @inheritdoc IERC712\n    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\n        return block.chainid == _INITIAL_CHAIN_ID ? _INITIAL_DOMAIN_SEPARATOR : _getDomainSeparator();\n    }\n\n    /* ============ Internal View/Pure Functions ============ */\n\n    /**\n     * @dev    Computes the EIP-712 domain separator.\n     * @return The EIP-712 domain separator.\n     */\n    function _getDomainSeparator() internal view returns (bytes32) {\n        return\n            keccak256(\n                abi.encode(\n                    _EIP712_DOMAIN_HASH,\n                    keccak256(bytes(_name)),\n                    _EIP712_VERSION_HASH,\n                    block.chainid,\n                    address(this)\n                )\n            );\n    }\n\n    /**\n     * @dev    Returns the digest to be signed, via EIP-712, given an internal digest (i.e. hash struct).\n     * @param  internalDigest_ The internal digest.\n     * @return The digest to be signed.\n     */\n    function _getDigest(bytes32 internalDigest_) internal view returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19\\x01\", DOMAIN_SEPARATOR(), internalDigest_));\n    }\n\n    /**\n     * @dev   Revert if the signature is expired.\n     * @param expiry_ Timestamp at which the signature expires or max uint256 for no expiry.\n     */\n    function _revertIfExpired(uint256 expiry_) internal view {\n        if (block.timestamp > expiry_) revert SignatureExpired(expiry_, block.timestamp);\n    }\n\n    /**\n     * @dev   Revert if the signature is invalid.\n     * @dev   We first validate if the signature is a valid ECDSA signature and return early if it is the case.\n     *        Then, we validate if it is a valid ERC-1271 signature, and return early if it is the case.\n     *        If not, we revert with the error from the ECDSA signature validation.\n     * @param signer_    The signer of the signature.\n     * @param digest_    The digest that was signed.\n     * @param signature_ The signature.\n     */\n    function _revertIfInvalidSignature(address signer_, bytes32 digest_, bytes memory signature_) internal view {\n        SignatureChecker.Error error_ = SignatureChecker.validateECDSASignature(signer_, digest_, signature_);\n\n        if (error_ == SignatureChecker.Error.NoError) return;\n\n        if (SignatureChecker.isValidERC1271Signature(signer_, digest_, signature_)) return;\n\n        _revertIfError(error_);\n    }\n\n    /**\n     * @dev    Returns the signer of a signed digest, via EIP-712, and reverts if the signature is invalid.\n     * @param  digest_ The digest that was signed.\n     * @param  v_      v of the signature.\n     * @param  r_      r of the signature.\n     * @param  s_      s of the signature.\n     * @return signer_ The signer of the digest.\n     */\n    function _getSignerAndRevertIfInvalidSignature(\n        bytes32 digest_,\n        uint8 v_,\n        bytes32 r_,\n        bytes32 s_\n    ) internal pure returns (address signer_) {\n        SignatureChecker.Error error_;\n\n        (error_, signer_) = SignatureChecker.recoverECDSASigner(digest_, v_, r_, s_);\n\n        _revertIfError(error_);\n    }\n\n    /**\n     * @dev   Revert if the signature is invalid.\n     * @param signer_ The signer of the signature.\n     * @param digest_ The digest that was signed.\n     * @param r_      An ECDSA/secp256k1 signature parameter.\n     * @param vs_     An ECDSA/secp256k1 short signature parameter.\n     */\n    function _revertIfInvalidSignature(address signer_, bytes32 digest_, bytes32 r_, bytes32 vs_) internal pure {\n        _revertIfError(SignatureChecker.validateECDSASignature(signer_, digest_, r_, vs_));\n    }\n\n    /**\n     * @dev   Revert if the signature is invalid.\n     * @param signer_ The signer of the signature.\n     * @param digest_ The digest that was signed.\n     * @param v_      v of the signature.\n     * @param r_      r of the signature.\n     * @param s_      s of the signature.\n     */\n    function _revertIfInvalidSignature(\n        address signer_,\n        bytes32 digest_,\n        uint8 v_,\n        bytes32 r_,\n        bytes32 s_\n    ) internal pure {\n        _revertIfError(SignatureChecker.validateECDSASignature(signer_, digest_, v_, r_, s_));\n    }\n\n    /**\n     * @dev   Revert if error.\n     * @param error_ The SignatureChecker Error enum.\n     */\n    function _revertIfError(SignatureChecker.Error error_) private pure {\n        if (error_ == SignatureChecker.Error.NoError) return;\n        if (error_ == SignatureChecker.Error.InvalidSignature) revert InvalidSignature();\n        if (error_ == SignatureChecker.Error.InvalidSignatureLength) revert InvalidSignatureLength();\n        if (error_ == SignatureChecker.Error.InvalidSignatureS) revert InvalidSignatureS();\n        if (error_ == SignatureChecker.Error.InvalidSignatureV) revert InvalidSignatureV();\n        if (error_ == SignatureChecker.Error.SignerMismatch) revert SignerMismatch();\n\n        revert InvalidSignature();\n    }\n}\n"
      },
      "lib/ttg/lib/common/src/libs/SignatureChecker.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\nimport { IERC1271 } from \"../interfaces/IERC1271.sol\";\n\n/**\n * @title  A library to handle ECDSA/secp256k1 and ERC1271 signatures, individually or in arbitrarily in combination.\n * @author M^0 Labs\n */\nlibrary SignatureChecker {\n    /* ============ Enums ============ */\n\n    /**\n     * @notice An enum representing the possible errors that can be emitted during signature validation.\n     * @param  NoError                No error occurred during signature validation.\n     * @param  InvalidSignature       The signature is invalid.\n     * @param  InvalidSignatureLength The signature length is invalid.\n     * @param  InvalidSignatureS      The signature parameter S is invalid.\n     * @param  InvalidSignatureV      The signature parameter V is invalid.\n     * @param  SignerMismatch         The signer does not match the recovered signer.\n     */\n    enum Error {\n        NoError,\n        InvalidSignature,\n        InvalidSignatureLength,\n        InvalidSignatureS,\n        InvalidSignatureV,\n        SignerMismatch\n    }\n\n    /* ============ Internal View/Pure Functions ============ */\n\n    /**\n     * @dev    Returns whether a signature is valid (ECDSA/secp256k1 or ERC1271) for a signer and digest.\n     * @dev    Signatures must not be used as unique identifiers since the `ecrecover` EVM opcode\n     *         allows for malleable (non-unique) signatures.\n     *         See https://github.com/OpenZeppelin/openzeppelin-contracts/security/advisories/GHSA-4h98-2769-gh6h\n     * @param  signer    The address of the account purported to have signed.\n     * @param  digest    The hash of the data that was signed.\n     * @param  signature A byte array signature.\n     * @return           Whether the signature is valid or not.\n     */\n    function isValidSignature(address signer, bytes32 digest, bytes memory signature) internal view returns (bool) {\n        return isValidECDSASignature(signer, digest, signature) || isValidERC1271Signature(signer, digest, signature);\n    }\n\n    /**\n     * @dev    Returns whether an ERC1271 signature is valid for a signer and digest.\n     * @param  signer    The address of the account purported to have signed.\n     * @param  digest    The hash of the data that was signed.\n     * @param  signature A byte array ERC1271 signature.\n     * @return           Whether the signature is valid or not.\n     */\n    function isValidERC1271Signature(\n        address signer,\n        bytes32 digest,\n        bytes memory signature\n    ) internal view returns (bool) {\n        (bool success, bytes memory result) = signer.staticcall(\n            abi.encodeCall(IERC1271.isValidSignature, (digest, signature))\n        );\n\n        return\n            success &&\n            result.length >= 32 &&\n            abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector);\n    }\n\n    /**\n     * @dev    Decodes an ECDSA/secp256k1 signature from a byte array to standard v, r, and s parameters.\n     * @param  signature A byte array ECDSA/secp256k1 signature.\n     * @return v         An ECDSA/secp256k1 signature parameter.\n     * @return r         An ECDSA/secp256k1 signature parameter.\n     * @return s         An ECDSA/secp256k1 signature parameter.\n     */\n    function decodeECDSASignature(bytes memory signature) internal pure returns (uint8 v, bytes32 r, bytes32 s) {\n        // ecrecover takes the signature parameters, and they can be decoded using assembly.\n        /// @solidity memory-safe-assembly\n        assembly {\n            r := mload(add(signature, 0x20))\n            s := mload(add(signature, 0x40))\n            v := byte(0, mload(add(signature, 0x60)))\n        }\n    }\n\n    /**\n     * @dev    Decodes an ECDSA/secp256k1 short signature as defined by EIP2098\n     *         from a byte array to standard v, r, and s parameters.\n     * @param  signature A byte array ECDSA/secp256k1 short signature.\n     * @return r         An ECDSA/secp256k1 signature parameter.\n     * @return vs        An ECDSA/secp256k1 short signature parameter.\n     */\n    function decodeShortECDSASignature(bytes memory signature) internal pure returns (bytes32 r, bytes32 vs) {\n        // ecrecover takes the signature parameters, and they can be decoded using assembly.\n        /// @solidity memory-safe-assembly\n        assembly {\n            r := mload(add(signature, 0x20))\n            vs := mload(add(signature, 0x40))\n        }\n    }\n\n    /**\n     * @dev    Returns whether an ECDSA/secp256k1 signature is valid for a signer and digest.\n     * @param  signer    The address of the account purported to have signed.\n     * @param  digest    The hash of the data that was signed.\n     * @param  signature A byte array ECDSA/secp256k1 signature (encoded r, s, v).\n     * @return           Whether the signature is valid or not.\n     */\n    function isValidECDSASignature(\n        address signer,\n        bytes32 digest,\n        bytes memory signature\n    ) internal pure returns (bool) {\n        if (signature.length == 64) {\n            (bytes32 r, bytes32 vs) = decodeShortECDSASignature(signature);\n            return isValidECDSASignature(signer, digest, r, vs);\n        }\n\n        return validateECDSASignature(signer, digest, signature) == Error.NoError;\n    }\n\n    /**\n     * @dev    Returns whether an ECDSA/secp256k1 short signature is valid for a signer and digest.\n     * @param  signer  The address of the account purported to have signed.\n     * @param  digest  The hash of the data that was signed.\n     * @param  r       An ECDSA/secp256k1 signature parameter.\n     * @param  vs      An ECDSA/secp256k1 short signature parameter.\n     * @return         Whether the signature is valid or not.\n     */\n    function isValidECDSASignature(address signer, bytes32 digest, bytes32 r, bytes32 vs) internal pure returns (bool) {\n        return validateECDSASignature(signer, digest, r, vs) == Error.NoError;\n    }\n\n    /**\n     * @dev    Returns the signer of an ECDSA/secp256k1 signature for some digest.\n     * @param  digest    The hash of the data that was signed.\n     * @param  signature A byte array ECDSA/secp256k1 signature.\n     * @return           An error, if any, that occurred during the signer recovery.\n     * @return           The address of the account recovered form the signature (0 if error).\n     */\n    function recoverECDSASigner(bytes32 digest, bytes memory signature) internal pure returns (Error, address) {\n        if (signature.length != 65) return (Error.InvalidSignatureLength, address(0));\n\n        (uint8 v, bytes32 r, bytes32 s) = decodeECDSASignature(signature);\n\n        return recoverECDSASigner(digest, v, r, s);\n    }\n\n    /**\n     * @dev    Returns the signer of an ECDSA/secp256k1 short signature for some digest.\n     * @dev    See https://eips.ethereum.org/EIPS/eip-2098\n     * @param  digest The hash of the data that was signed.\n     * @param  r      An ECDSA/secp256k1 signature parameter.\n     * @param  vs     An ECDSA/secp256k1 short signature parameter.\n     * @return        An error, if any, that occurred during the signer recovery.\n     * @return        The address of the account recovered form the signature (0 if error).\n     */\n    function recoverECDSASigner(bytes32 digest, bytes32 r, bytes32 vs) internal pure returns (Error, address) {\n        unchecked {\n            // We do not check for an overflow here since the shift operation results in 0 or 1.\n            uint8 v = uint8((uint256(vs) >> 255) + 27);\n            bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n            return recoverECDSASigner(digest, v, r, s);\n        }\n    }\n\n    /**\n     * @dev    Returns the signer of an ECDSA/secp256k1 signature for some digest.\n     * @param  digest The hash of the data that was signed.\n     * @param  v      An ECDSA/secp256k1 signature parameter.\n     * @param  r      An ECDSA/secp256k1 signature parameter.\n     * @param  s      An ECDSA/secp256k1 signature parameter.\n     * @return        An error, if any, that occurred during the signer recovery.\n     * @return signer The address of the account recovered form the signature (0 if error).\n     */\n    function recoverECDSASigner(\n        bytes32 digest,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal pure returns (Error, address signer) {\n        // Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}.\n        if (uint256(s) > uint256(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0))\n            return (Error.InvalidSignatureS, address(0));\n\n        if (v != 27 && v != 28) return (Error.InvalidSignatureV, address(0));\n\n        signer = ecrecover(digest, v, r, s);\n\n        return (signer == address(0)) ? (Error.InvalidSignature, address(0)) : (Error.NoError, signer);\n    }\n\n    /**\n     * @dev    Returns an error, if any, in validating an ECDSA/secp256k1 signature for a signer and digest.\n     * @param  signer    The address of the account purported to have signed.\n     * @param  digest    The hash of the data that was signed.\n     * @param  signature A byte array ERC1271 signature.\n     * @return           An error, if any, that occurred during the signer recovery.\n     */\n    function validateECDSASignature(\n        address signer,\n        bytes32 digest,\n        bytes memory signature\n    ) internal pure returns (Error) {\n        (Error recoverError, address recoveredSigner) = recoverECDSASigner(digest, signature);\n\n        return (recoverError == Error.NoError) ? validateRecoveredSigner(signer, recoveredSigner) : recoverError;\n    }\n\n    /**\n     * @dev    Returns an error, if any, in validating an ECDSA/secp256k1 short signature for a signer and digest.\n     * @param  signer The address of the account purported to have signed.\n     * @param  digest The hash of the data that was signed.\n     * @param  r      An ECDSA/secp256k1 signature parameter.\n     * @param  vs     An ECDSA/secp256k1 short signature parameter.\n     * @return        An error, if any, that occurred during the signer recovery.\n     */\n    function validateECDSASignature(\n        address signer,\n        bytes32 digest,\n        bytes32 r,\n        bytes32 vs\n    ) internal pure returns (Error) {\n        (Error recoverError, address recoveredSigner) = recoverECDSASigner(digest, r, vs);\n\n        return (recoverError == Error.NoError) ? validateRecoveredSigner(signer, recoveredSigner) : recoverError;\n    }\n\n    /**\n     * @dev    Returns an error, if any, in validating an ECDSA/secp256k1 signature for a signer and digest.\n     * @param  signer The address of the account purported to have signed.\n     * @param  digest The hash of the data that was signed.\n     * @param  v      An ECDSA/secp256k1 signature parameter.\n     * @param  r      An ECDSA/secp256k1 signature parameter.\n     * @param  s      An ECDSA/secp256k1 signature parameter.\n     * @return        An error, if any, that occurred during the signer recovery.\n     */\n    function validateECDSASignature(\n        address signer,\n        bytes32 digest,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal pure returns (Error) {\n        (Error recoverError, address recoveredSigner) = recoverECDSASigner(digest, v, r, s);\n\n        return (recoverError == Error.NoError) ? validateRecoveredSigner(signer, recoveredSigner) : recoverError;\n    }\n\n    /**\n     * @dev    Returns an error if `signer` is not `recoveredSigner`.\n     * @param  signer          The address of the some signer.\n     * @param  recoveredSigner The address of the some recoveredSigner.\n     * @return                 An error if `signer` is not `recoveredSigner`.\n     */\n    function validateRecoveredSigner(address signer, address recoveredSigner) internal pure returns (Error) {\n        return (signer == recoveredSigner) ? Error.NoError : Error.SignerMismatch;\n    }\n}\n"
      },
      "lib/ttg/lib/common/src/interfaces/IERC1271.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.23;\n\n/**\n * @title  Standard Signature Validation Method for Contracts via EIP-1271.\n * @author M^0 Labs\n * @dev    The interface as defined by EIP-1271: https://eips.ethereum.org/EIPS/eip-1271\n */\ninterface IERC1271 {\n    /**\n     * @dev    Returns a specific magic value if the provided signature is valid for the provided digest.\n     * @param  digest     Hash of the data purported to have been signed.\n     * @param  signature  Signature byte array associated with the digest.\n     * @return magicValue Magic value 0x1626ba7e if the signature is valid.\n     */\n    function isValidSignature(bytes32 digest, bytes memory signature) external view returns (bytes4 magicValue);\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "common/=lib/protocol/lib/common/src/",
        "contract-test-utils/=lib/ttg/lib/erc20-helper/lib/contract-test-utils/contracts/",
        "ds-test/=lib/protocol/lib/solmate/lib/ds-test/src/",
        "erc20-helper/=lib/ttg/lib/erc20-helper/src/",
        "forge-std/=lib/forge-std/src/",
        "protocol/=lib/protocol/",
        "solmate/=lib/protocol/lib/solmate/src/",
        "ttg/=lib/ttg/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 999999
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "shanghai",
      "viaIR": false,
      "libraries": {}
    }
  }}