TTSwap_Market

Description:

Multi-signature wallet contract requiring multiple confirmations for transaction execution.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "settings": {
    "viaIR": true,
    "evmVersion": "cancun",
    "optimizer": {
      "enabled": true,
      "runs": 100
    },
    "outputSelection": {
      "*": {
        "*": [
          "evm.bytecode",
          "evm.deployedBytecode",
          "devdoc",
          "userdoc",
          "metadata",
          "abi"
        ]
      }
    },
    "remappings": [
      "ds-test/=lib/forge-std/lib/ds-test/src/",
      "forge-std/=lib/forge-std/src/",
      "@openzeppelin-upgradeable/contracts/=lib/openzeppelin-contracts-upgradeable/contracts/",
      "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
      "forge-gas-snapshot/=lib/forge-gas-snapshot/",
      "forge-std-1.10.0/=dependencies/forge-std-1.10.0/",
      "forge-std/=lib/forge-std/",
      "permit2/=lib/permit2/",
      "solmate/=lib/solmate/",
      "@openzeppelin-upgradeable/contracts/=lib/openzeppelin-contracts-upgradeable/contracts/",
      "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
      "forge-gas-snapshot/=lib/forge-gas-snapshot/",
      "forge-std-1.10.0/=dependencies/forge-std-1.10.0/",
      "forge-std/=lib/forge-std/",
      "permit2/=lib/permit2/",
      "solmate/=lib/solmate/",
      "@openzeppelin-upgradeable/contracts/=lib/openzeppelin-contracts-upgradeable/contracts/",
      "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
      "forge-gas-snapshot/=lib/forge-gas-snapshot/",
      "forge-std-1.10.0/=dependencies/forge-std-1.10.0/",
      "forge-std/=lib/forge-std/",
      "permit2/=lib/permit2/",
      "solmate/=lib/solmate/"
    ]
  },
  "sources": {
    "src/TTSwap_Market.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.29;

import {I_TTSwap_Market, S_ProofState, S_GoodState, S_ProofKey, S_GoodTmpState} from "./interfaces/I_TTSwap_Market.sol";
import {L_Good} from "./libraries/L_Good.sol";
import {L_Transient} from "./libraries/L_Transient.sol";
import {TTSwapError} from "./libraries/L_Error.sol";
import {L_Proof, L_ProofIdLibrary} from "./libraries/L_Proof.sol";
import {L_GoodConfigLibrary} from "./libraries/L_GoodConfig.sol";
import {L_UserConfigLibrary} from "./libraries/L_UserConfig.sol";
import {L_CurrencyLibrary} from "./libraries/L_Currency.sol";
import {L_TTSwapUINT256Library, toTTSwapUINT256, add, lowerprice} from "./libraries/L_TTSwapUINT256.sol";
import {IMulticall_v4} from "./interfaces/IMulticall_v4.sol";
import {I_TTSwap_Token} from "./interfaces/I_TTSwap_Token.sol";

/**
 * @title TTSwap_Market
 * @author ttswap.exchange@gmail.com
 * @dev Core market contract for TTSwap protocol that manages goods trading, investing, and staking operations
 * @notice This contract implements a decentralized market system with the following key features:
 * - Meta good, value goods, and normal goods management
 * - Automated market making (AMM) with configurable fees
 * - Investment and disinvestment mechanisms
 * - Commission distribution system
 * website http://www.ttswap.io
 * twitter https://x.com/ttswapfinance
 * telegram https://t.me/ttswapfinance
 * discord https://discord.gg/XygqnmQgX3
 */
contract TTSwap_Market is I_TTSwap_Market, IMulticall_v4 {
    using L_GoodConfigLibrary for uint256;
    using L_UserConfigLibrary for uint256;
    using L_ProofIdLibrary for S_ProofKey;
    using L_TTSwapUINT256Library for uint256;
    using L_Good for S_GoodState;
    using L_Proof for S_ProofState;
    using L_CurrencyLibrary for address;

    /**
     * @dev Address of the official TTS token contract
     * @notice Handles:
     * - Minting rewards for market participation
     * - Staking operations and rewards
     * - Referral tracking and rewards
     * - Governance token functionality
     */
    I_TTSwap_Token private immutable TTS_CONTRACT;

    /// @notice Address of the security keeper
    /// @dev The address of the security keeper
    /// @custom:security The address of the security keeper when deploy market contract
    /// @custom:security The address of the security keeper will be removed by market admin when contract run safety
    address internal securitykeeper;

    /**
     * @dev Mapping of good addresses to their state information
     * @notice Stores the complete state of each good including:
     * - Current trading state(invest quantity & current quantity)
     * - Investment state (invest shares & invest value)
     * - Owner information
     * - Configuration parameters
     */
    mapping(address goodid => S_GoodState) private goods;

    /**
     * @dev Mapping of proof IDs to their state information
     * @notice Records all investment proofs in the system:
     * shares amount0:normal good shares amount1:value good shares
     * state amount0:total value : amount1:total actual value
     * invest amount0:normal good virtual quantity amount1:normal good actual quantity
     * valueinvest amount0:value good virtual quantity amount1:value good actual quantity
     */
    mapping(uint256 proofid => S_ProofState) private proofs;

    /**
     * @dev Constructor for TTSwap_Market
     * @param _TTS_Contract The address of the official token contract
     * @param _securitykeeper The address of the security keeper
     */
    constructor(I_TTSwap_Token _TTS_Contract, address _securitykeeper) {
        TTS_CONTRACT = _TTS_Contract;
        securitykeeper = _securitykeeper;
    }

    /// only market admin can execute
    modifier onlyMarketadmin() {
        if (!TTS_CONTRACT.userConfig(msg.sender).isMarketAdmin())
            revert TTSwapError(1);
        _;
    }

    /// only market manager can execute
    modifier onlyMarketor() {
        if (!TTS_CONTRACT.userConfig(msg.sender).isMarketManager())
            revert TTSwapError(2);
        _;
    }

    /// run when eth token transfer to market contract
    modifier msgValue() {
        L_Transient.checkbefore();
        _;
        L_Transient.checkafter();
    }

    /// @notice This will revert if the contract is locked
    modifier noReentrant() {
        if (L_Transient.get() != address(0)) revert TTSwapError(3);
        L_Transient.set(msg.sender);
        _;
        L_Transient.set(address(0));
    }

    /// @notice Enables calling multiple methods in a single call to the contract
    /// @inheritdoc IMulticall_v4
    function multicall(
        bytes[] calldata data
    ) external payable msgValue returns (bytes[] memory results) {
        results = new bytes[](data.length);
        for (uint256 i = 0; i < data.length; i++) {
            (bool success, bytes memory result) = address(this).delegatecall(
                data[i]
            );

            if (!success) {
                // bubble up the revert reason
                assembly {
                    revert(add(result, 0x20), mload(result))
                }
            }

            results[i] = result;
        }
    }

    /**
     * @dev Initializes a meta good with initial liquidity
     * @param _erc20address The address of the ERC20 token to be used as the meta good
     * @param _initial The initial liquidity amounts:
     *        - amount0: Initial token value
     *        - amount1: Initial token amount
     * @param _goodConfig Configuration parameters for the good:
     *        - Fee rates (trading, investment)
     *        - Trading limits (min/max amounts)
     *        - Special flags ( emergency pause)
     * @param data Additional data for token transfer
     * @return bool Success status of the initialization
     * @notice This function:
     * - Creates a new meta good with specified parameters
     * - Sets up initial liquidity pool
     * - Mints corresponding tokens to the market creator
     * - Initializes proof tracking
     * - Emits initialization events
     * @custom:security Only callable by market admin
     */
    /// @inheritdoc I_TTSwap_Market
    function initMetaGood(
        address _erc20address,
        uint256 _initial,
        uint256 _goodConfig,
        bytes calldata data
    ) external payable onlyMarketadmin msgValue returns (bool) {
        if (!_goodConfig.isvaluegood()) revert TTSwapError(4);
        if (goods[_erc20address].owner != address(0)) revert TTSwapError(5);
        _erc20address.transferFrom(msg.sender, _initial.amount1(), data);
        goods[_erc20address].init(_initial, _goodConfig);
        /// update good to value good & initialize good config
        goods[_erc20address].modifyGoodConfig(0x30d4204000000000000000000000000000000000000000000000000000000000); //6*2**28+ 1*2**24+ 5*2**21+8*2**16+8*2**11+2*2**6
        goods[_erc20address].modifyGoodCoreConfig(0x8000000000000000000000000000000000000000000000000000000000000000);//2**255
        uint256 proofid = S_ProofKey(msg.sender, _erc20address, address(0))
            .toId();
        proofs[proofid].updateInvest(
            _erc20address,
            address(0),
            toTTSwapUINT256(_initial.amount1(), 0),
            toTTSwapUINT256(_initial.amount0(), _initial.amount0()),
            toTTSwapUINT256(_initial.amount1(), _initial.amount1()),
            0
        );
        uint128 construct = L_Proof.stake(
            TTS_CONTRACT,
            msg.sender,
            _initial.amount0()
        );
        emit e_initMetaGood(
            proofid,
            _erc20address,
            construct,
            _goodConfig,
            _initial
        );
        return true;
    }

    /**
     * @dev Initializes a good
     * @param _valuegood The value good ID
     * @param _initial The initial balance,amount0 is the amount of the normal good,amount1 is the amount of the value good
     * @param _erc20address The address of the ERC20 token
     * @param _goodConfig The good configuration
     * @param _normaldata The data of the normal good
     * @param _valuedata The data of the value good
     * @return bool Returns true if successful
     */
    /// @inheritdoc I_TTSwap_Market
    function initGood(
        address _valuegood,
        uint256 _initial,
        address _erc20address,
        uint256 _goodConfig,
        bytes calldata _normaldata,
        bytes calldata _valuedata
    ) external payable override noReentrant msgValue returns (bool) {
        if (_initial.amount0() < 500000 || _initial.amount0() > 2 ** 109)
            revert TTSwapError(36);
        if (!goods[_valuegood].goodConfig.isvaluegood()) {
            revert TTSwapError(6);
        }
        if (goods[_erc20address].owner != address(0)) revert TTSwapError(5);
        _erc20address.transferFrom(msg.sender, _initial.amount0(), _normaldata);
        _valuegood.transferFrom(msg.sender, _initial.amount1(), _valuedata);
        L_Good.S_GoodInvestReturn memory investResult;
        (investResult.goodShares, investResult.goodValues) = goods[_valuegood]
            .investState
            .amount01();
        (
            investResult.goodInvestQuantity,
            investResult.goodCurrentQuantity
        ) = goods[_valuegood].currentState.amount01();
        goods[_valuegood].investGood(_initial.amount1(), investResult, 1);
        if (investResult.investValue < 500000000) revert TTSwapError(35);
        goods[_erc20address].init(
            toTTSwapUINT256(investResult.investValue, _initial.amount0()),
            _goodConfig
        );
        uint256 proofId = S_ProofKey(msg.sender, _erc20address, _valuegood)
            .toId();

        proofs[proofId] = S_ProofState(
            _erc20address,
            _valuegood,
            toTTSwapUINT256(_initial.amount0(), investResult.investShare),
            toTTSwapUINT256(investResult.investValue, investResult.investValue),
            toTTSwapUINT256(_initial.amount0(), _initial.amount0()),
            toTTSwapUINT256(
                investResult.investQuantity,
                investResult.investQuantity
            )
        );

        emit e_initGood(
            proofId,
            _erc20address,
            _valuegood,
            _goodConfig,
            L_Proof.stake(
                TTS_CONTRACT,
                msg.sender,
                investResult.investValue * 2
            ),
            toTTSwapUINT256(_initial.amount0(), investResult.investValue), // amount0: the quantity of the normal good,amount1: the value of the value good
            toTTSwapUINT256(
                investResult.investFeeQuantity, // amount0: the fee of the value good
                investResult.investQuantity // amount1: the quantity of the value good
            )
        );
        return true;
    }

    /**
     * @dev Executes a buy order between two goods
     * @param _goodid1 The address of the input good
     * @param _goodid2 The address of the output good
     * @param _swapQuantity The amount of _goodid1 to swap
     *        - amount0: The quantity of the input good
     *        - amount1: The limit quantity of the output good
     * @param _side 0:for pay 1for buy
     * @param _recipent The address to receive referral rewards
     * @param data Additional data for token transfer
     * @return good1change The amount of _goodid1 used:
     *         - amount0: Trading fees
     *         - amount1: Actual swap amount
     * @return good2change The amount of _goodid2 received:
     *         - amount0: Trading fees
     *         - amount1: Actual received amount
     * @notice This function:
     * - Calculates optimal swap amounts using AMM formulas
     * - Applies trading fees and updates fee states
     * - Updates good states and reserves
     * - Handles referral rewards and distributions
     * - Emits trade events with detailed information
     * @custom:security Protected by reentrancy guard
     * @custom:security Validates input parameters and state
     */
    /// @inheritdoc I_TTSwap_Market

    function buyGood(
        address _goodid1,
        address _goodid2,
        uint256 _swapQuantity,
        uint128 _side,
        address _recipent,
        bytes calldata data
    )
        external
        payable
        noReentrant
        msgValue
        returns (uint256 good1change, uint256 good2change)
    {
        if (_side > 1) revert TTSwapError(8);
        if (_goodid1 == _goodid2) revert TTSwapError(9);
        if (goods[_goodid1].goodConfig.isFreeze()) revert TTSwapError(10);
        if (goods[_goodid2].goodConfig.isFreeze()) revert TTSwapError(11);
        if (goods[_goodid1].currentState == 0) revert TTSwapError(12);
        if (goods[_goodid2].currentState == 0) revert TTSwapError(13);
        if (_side == 1) {
            if (_recipent != address(0) && _recipent != msg.sender) {
                TTS_CONTRACT.setReferral(msg.sender, _recipent);
            }
            if (
                goods[_goodid1].currentState.amount1() +
                    _swapQuantity.amount0() >
                goods[_goodid1].currentState.amount1() *
                    2 -
                    goods[_goodid1].goodConfig.amount1()
            ) revert TTSwapError(33);
            L_Good.swapCache memory swapcache = L_Good.swapCache({
                remainQuantity: _swapQuantity.amount0(),
                outputQuantity: 0,
                feeQuantity: 0,
                swapvalue: 0,
                good1value: goods[_goodid1].investState.amount1(),
                good2value: goods[_goodid2].investState.amount1(),
                good1currentState: goods[_goodid1].currentState,
                good1config: goods[_goodid1].goodConfig,
                good2currentState: goods[_goodid2].currentState,
                good2config: goods[_goodid2].goodConfig
            });

            L_Good.swapCompute1(swapcache);

            if (swapcache.swapvalue < 1_000_000) revert TTSwapError(14);
            if (
                swapcache.outputQuantity < _swapQuantity.amount1() &&
                _swapQuantity.amount1() > 0
            ) revert TTSwapError(15);
            if (
                swapcache.good2currentState.amount1() <
                (swapcache.good2config.amount1() * 11) / 10
            ) revert TTSwapError(16);

            if (
                swapcache.good2currentState.amount1() <
                swapcache.good2currentState.amount0() / 10
            ) revert TTSwapError(16);

            swapcache.good1currentState = add(
                swapcache.good1currentState,
                toTTSwapUINT256(swapcache.feeQuantity, _swapQuantity.amount0())
            );
            good1change = toTTSwapUINT256(
                swapcache.feeQuantity,
                _swapQuantity.amount0() - swapcache.feeQuantity
            );
            // compute Token2 fee quantity
            _side = swapcache.good2config.getBuyFee(swapcache.outputQuantity);
            // add fee quantity to token2 pool
            swapcache.good2currentState = add(
                swapcache.good2currentState,
                toTTSwapUINT256(_side, _side)
            );
            good2change = toTTSwapUINT256(_side, swapcache.outputQuantity);
            goods[_goodid1].swapCommit(swapcache.good1currentState);
            goods[_goodid2].swapCommit(swapcache.good2currentState);
            _goodid1.transferFrom(msg.sender, _swapQuantity.amount0(), data);
            _goodid2.safeTransfer(msg.sender, good2change.amount1() - _side);
            emit e_buyGood(
                _goodid1,
                _goodid2,
                swapcache.swapvalue,
                good1change,
                good2change
            );
        } else {
            if (_recipent == address(0)) revert TTSwapError(32);
            L_Good.swapCache memory swapcache = L_Good.swapCache({
                remainQuantity: _swapQuantity.amount1(),
                outputQuantity: 0,
                feeQuantity: 0,
                swapvalue: 0,
                good1value: goods[_goodid1].investState.amount1(),
                good2value: goods[_goodid2].investState.amount1(),
                good1currentState: goods[_goodid1].currentState,
                good1config: goods[_goodid1].goodConfig,
                good2currentState: goods[_goodid2].currentState,
                good2config: goods[_goodid2].goodConfig
            });
            L_Good.swapCompute2(swapcache);
            _side = swapcache.good1config.getSellFee(swapcache.outputQuantity);
            good1change = toTTSwapUINT256(_side, swapcache.outputQuantity);
            if (swapcache.swapvalue < 1_000_000) revert TTSwapError(14);
            if (
                good1change.amount1() > _swapQuantity.amount0() &&
                _swapQuantity.amount0() > 0
            ) revert TTSwapError(15);
            if (
                swapcache.good2currentState.amount1() <
                (swapcache.good2config.amount1() * 11) / 10 
            ) revert TTSwapError(16);

            if (
                swapcache.good2currentState.amount1() <
                swapcache.good2currentState.amount0() / 10
            ) revert TTSwapError(16);
            if (
                goods[_goodid1].currentState.amount1() +
                    _swapQuantity.amount0() >
                goods[_goodid1].currentState.amount0() *
                    2 -
                    goods[_goodid1].goodConfig.amount1()
            ) revert TTSwapError(33);
            swapcache.good1currentState = add(
                swapcache.good1currentState,
                toTTSwapUINT256(_side, _side)
            );
            good2change = toTTSwapUINT256(
                swapcache.feeQuantity,
                _swapQuantity.amount1() - swapcache.feeQuantity
            );
            _goodid1.transferFrom(
                msg.sender,
                good1change.amount1() + _side,
                data
            );
            goods[_goodid1].swapCommit(swapcache.good1currentState);
            goods[_goodid2].swapCommit(swapcache.good2currentState);
            _goodid2.safeTransfer(_recipent, _swapQuantity.amount1());
            emit e_buyGood(
                _goodid1,
                _goodid2,
                uint256(swapcache.swapvalue) * 2 ** 128,
                good1change,
                good2change
            );
        }
    }

    /**
     * @dev Simulates a buy order between two goods to check expected amounts
     * @param _goodid1 The address of the input good
     * @param _goodid2 The address of the output good
     * @param _swapQuantity The amount of _goodid1 to swap
     *        - amount0: The quantity of the input good
     *        - amount1: The limit quantity of the output good
     * @param _side 1:for buy 0:for pay
     * @return good1change The expected amount of _goodid1 to be used:
     *         - amount0: Expected trading fees
     *         - amount1: Expected swap amount
     * @return good2change The expected amount of _goodid2 to be received:
     *         - amount0: Expected trading fees
     *         - amount1: Expected received amount
     * @notice This function:
     * - Simulates the buyGood operation without executing it
     * - Uses the same AMM formulas as buyGood
     * - Validates input parameters and market state
     * - Returns expected amounts including fees
     * - Useful for frontend price quotes and transaction previews
     * @custom:security View function, does not modify state
     * @custom:security Reverts if:
     * - Either good is not initialized
     * - Swap quantity is zero
     * - Same good is used for both input and output
     * - Trade times exceeds 200
     * - Insufficient liquidity for the swap
     */
    /// @inheritdoc I_TTSwap_Market
    function buyGoodCheck(
        address _goodid1,
        address _goodid2,
        uint256 _swapQuantity,
        bool _side
    ) external view returns (uint256 good1change, uint256 good2change) {
        if (_side) {
            L_Good.swapCache memory swapcache = L_Good.swapCache({
                remainQuantity: _swapQuantity.amount0(),
                outputQuantity: 0,
                feeQuantity: 0,
                swapvalue: 0,
                good1value: goods[_goodid1].investState.amount1(),
                good2value: goods[_goodid2].investState.amount1(),
                good1currentState: goods[_goodid1].currentState,
                good1config: goods[_goodid1].goodConfig,
                good2currentState: goods[_goodid2].currentState,
                good2config: goods[_goodid2].goodConfig
            });
            L_Good.swapCompute1(swapcache);
            good1change = toTTSwapUINT256(
                swapcache.feeQuantity,
                _swapQuantity.amount0() - swapcache.feeQuantity
            );
            good2change = toTTSwapUINT256(
                swapcache.good2config.getBuyFee(swapcache.outputQuantity),
                swapcache.outputQuantity
            );
        } else {
            L_Good.swapCache memory swapcache = L_Good.swapCache({
                remainQuantity: _swapQuantity.amount1(),
                outputQuantity: 0,
                feeQuantity: 0,
                swapvalue: 0,
                good1value: goods[_goodid1].investState.amount1(),
                good2value: goods[_goodid2].investState.amount1(),
                good1currentState: goods[_goodid1].currentState,
                good1config: goods[_goodid1].goodConfig,
                good2currentState: goods[_goodid2].currentState,
                good2config: goods[_goodid2].goodConfig
            });
            L_Good.swapCompute2(swapcache);
            good1change = toTTSwapUINT256(
                goods[_goodid1].goodConfig.getSellFee(swapcache.outputQuantity),
                swapcache.outputQuantity
            );
            good2change = toTTSwapUINT256(
                swapcache.feeQuantity,
                _swapQuantity.amount1() - swapcache.feeQuantity
            );
        }
    }

    /**
     * @dev Invests in a good with optional value good backing
     * @param _togood The address of the good to invest in
     * @param _valuegood The address of the value good (can be address(0))
     * @param _quantity The amount to invest _togood
     * @param data1 Additional data for _togood transfer
     * @param data2 Additional data for _valuegood transfer
     * @return bool Success status of the investment
     * @notice This function:
     * - Processes investment in the target good
     * - Optionally processes value good investment
     * - Updates proof state
     * - Mints corresponding tokens
     * - Calculates and distributes fees
     */
    /// @inheritdoc I_TTSwap_Market
    function investGood(
        address _togood,
        address _valuegood,
        uint128 _quantity,
        bytes calldata data1,
        bytes calldata data2
    ) external payable override noReentrant msgValue returns (bool) {
        L_Good.S_GoodInvestReturn memory normalInvest_;
        L_Good.S_GoodInvestReturn memory valueInvest_;
        if (_togood == _valuegood) revert TTSwapError(9);
        if (goods[_togood].goodConfig.isFreeze()) revert TTSwapError(10);
        if (goods[_togood].currentState == 0) revert TTSwapError(12);
        if (
            !(goods[_togood].goodConfig.isvaluegood() ||
                goods[_valuegood].goodConfig.isvaluegood())
        ) revert TTSwapError(17);
        if (goods[_togood].currentState.amount1() + _quantity > 2 ** 109)
            revert TTSwapError(18);

        uint128 enpower = goods[_togood].goodConfig.getPower();
        if (_valuegood != address(0)) {
            enpower = enpower < goods[_valuegood].goodConfig.getPower()
                ? enpower
                : goods[_valuegood].goodConfig.getPower();
        }
        _togood.transferFrom(msg.sender, _quantity, data1);
        (normalInvest_.goodShares, normalInvest_.goodValues) = goods[_togood]
            .investState
            .amount01();
        (
            normalInvest_.goodInvestQuantity,
            normalInvest_.goodCurrentQuantity
        ) = goods[_togood].currentState.amount01();
        goods[_togood].investGood(_quantity, normalInvest_, enpower);
        if (normalInvest_.investValue < 1000000) revert TTSwapError(38);
        if (_valuegood != address(0)) {
            if (goods[_valuegood].goodConfig.isFreeze()) revert TTSwapError(11);
            if (goods[_valuegood].currentState == 0) revert TTSwapError(13);
            (valueInvest_.goodShares, valueInvest_.goodValues) = goods[
                _valuegood
            ].investState.amount01();
            (
                valueInvest_.goodInvestQuantity,
                valueInvest_.goodCurrentQuantity
            ) = goods[_valuegood].currentState.amount01();
            valueInvest_.investQuantity = toTTSwapUINT256(
                valueInvest_.goodCurrentQuantity,
                valueInvest_.goodValues
            ).getamount0fromamount1(normalInvest_.investValue);
            valueInvest_.investQuantity = goods[_valuegood]
                .goodConfig
                .getInvestFullFee(valueInvest_.investQuantity);

            goods[_valuegood].investGood(
                valueInvest_.investQuantity,
                valueInvest_,
                enpower
            );
            _valuegood.transferFrom(
                msg.sender,
                valueInvest_.investQuantity /
                    enpower +
                    valueInvest_.investFeeQuantity,
                data2
            );
        }

        uint256 proofNo = S_ProofKey(msg.sender, _togood, _valuegood).toId();
        uint128 investvalue = normalInvest_.investValue;

        investvalue = (normalInvest_.investValue / enpower);
        proofs[proofNo].updateInvest(
            _togood,
            _valuegood,
            toTTSwapUINT256(
                normalInvest_.investShare,
                valueInvest_.investShare
            ),
            toTTSwapUINT256(normalInvest_.investValue, investvalue),
            toTTSwapUINT256(
                normalInvest_.investQuantity,
                normalInvest_.investQuantity / enpower //real quantity
            ),
            toTTSwapUINT256(
                valueInvest_.investQuantity,
                valueInvest_.investQuantity / enpower
            )
        );
        emit e_investGood(
            proofNo,
            _togood,
            _valuegood,
            toTTSwapUINT256(normalInvest_.investValue, investvalue),
            toTTSwapUINT256(
                normalInvest_.investFeeQuantity,
                normalInvest_.investQuantity
            ),
            toTTSwapUINT256(
                valueInvest_.investFeeQuantity,
                valueInvest_.investQuantity
            )
        );
        investvalue = _valuegood == address(0) ? investvalue : investvalue * 2;
        L_Proof.stake(TTS_CONTRACT, msg.sender, investvalue);
        return true;
    }

    /**
     * @dev Disinvests from a proof by withdrawing invested tokens and collecting profits
     * @param _proofid The ID of the proof to disinvest from
     * @param _goodQuantity The amount of normal good tokens to disinvest
     * @param _gate The address to receive gate rewards (falls back to DAO admin if banned)
     * @return uint128 The profit amount from normal good disinvestment
     * @return uint128 The profit amount from value good disinvestment (if applicable)
     * @notice This function:
     * - Validates proof ownership and state
     * - Processes disinvestment for both normal and value goods
     * - Handles commission distribution and fee collection
     * - Updates proof state and burns tokens
     * - Distributes rewards to gate and referrer
     * - Unstakes TTS tokens
     * @custom:security Protected by noReentrant modifier
     * @custom:security Reverts if:
     * - Proof ID does not match sender's proof
     * - Invalid proof state
     * - Insufficient balance for disinvestment
     */
    /// @inheritdoc I_TTSwap_Market
    function disinvestProof(
        uint256 _proofid,
        uint128 _goodshares,
        address _gate
    ) external override noReentrant returns (uint128, uint128) {
        if (
            S_ProofKey(
                msg.sender,
                proofs[_proofid].currentgood,
                proofs[_proofid].valuegood
            ).toId() != _proofid
        ) {
            revert TTSwapError(19);
        }

        L_Good.S_GoodDisinvestReturn memory disinvestNormalResult1_;
        L_Good.S_GoodDisinvestReturn memory disinvestValueResult2_;
        address normalgood = proofs[_proofid].currentgood;
        if (goods[normalgood].goodConfig.isFreeze()) revert TTSwapError(10);
        address valuegood = proofs[_proofid].valuegood;
        uint256 divestvalue;
        address referal = TTS_CONTRACT.getreferral(msg.sender);
        _gate = TTS_CONTRACT.userConfig(_gate).isBan() ? address(0) : _gate;
        referal = _gate == referal ? address(0) : referal;
        referal = TTS_CONTRACT.userConfig(referal).isBan()
            ? address(0)
            : referal;
        (disinvestNormalResult1_, disinvestValueResult2_, divestvalue) = goods[
            normalgood
        ].disinvestGood(
                goods[valuegood],
                proofs[_proofid],
                L_Good.S_GoodDisinvestParam(_goodshares, _gate, referal)
            );

        uint256 tranferamount = goods[normalgood].commission[msg.sender];

        if (tranferamount > 1) {
            goods[normalgood].commission[msg.sender] = 1;
            normalgood.safeTransfer(msg.sender, tranferamount - 1);
        }
        if (valuegood != address(0)) {
            if (goods[valuegood].goodConfig.isFreeze()) revert TTSwapError(10);
            tranferamount = goods[valuegood].commission[msg.sender];
            if (tranferamount > 1) {
                goods[valuegood].commission[msg.sender] = 1;
                valuegood.safeTransfer(msg.sender, tranferamount - 1);
            }
        }
        L_Proof.unstake(TTS_CONTRACT, msg.sender, divestvalue.amount0());

        emit e_disinvestProof(
            _proofid,
            normalgood,
            valuegood,
            _gate,
            divestvalue,
            toTTSwapUINT256(
                disinvestNormalResult1_.profit,
                disinvestNormalResult1_.vitualDisinvestQuantity
            ),
            toTTSwapUINT256(
                disinvestNormalResult1_.actual_fee,
                disinvestNormalResult1_.actualDisinvestQuantity
            ),
            toTTSwapUINT256(
                disinvestValueResult2_.profit,
                disinvestValueResult2_.vitualDisinvestQuantity
            ),
            toTTSwapUINT256(
                disinvestValueResult2_.actual_fee,
                disinvestValueResult2_.actualDisinvestQuantity
            )
        );
        return (disinvestNormalResult1_.profit, disinvestValueResult2_.profit);
    }

    /**
     * @dev Compares the current trading states of two goods to determine if the first good is in a higher iteration
     * @param good1 The address of the first good to compare
     * @param good2 The address of the second good to compare
     * @param compareprice the price of use good2 for good1
     * @return bool Returns true if good1's current state is higher than good2's, false otherwise
     * @notice This function:
     * - Compares the current trading iterations (states) of two goods
     * - Used to determine the trading order and eligibility for operations
     * - Essential for maintaining trading synchronization between goods
     * - Returns false if either good is not registered (state = 0)
     * @custom:security This is a view function with no state modifications
     * @custom:security Returns false for unregistered goods to prevent invalid operations
     */
    /// @inheritdoc I_TTSwap_Market
    function ishigher(
        address goodid,
        address valuegood,
        uint256 compareprice
    ) external view override returns (bool) {
        return
            lowerprice(
                toTTSwapUINT256(
                    goods[goodid].investState.amount1(),
                    goods[goodid].currentState.amount1()
                ),
                toTTSwapUINT256(
                    goods[valuegood].investState.amount1(),
                    goods[valuegood].currentState.amount1()
                ),
                compareprice
            );
    }

    /**
     * @dev Retrieves the current state of two goods in a single call
     * @param good1 The address of the first good to query
     * @param good2 The address of the second good to query
     * @return good1correntstate The current state of the first good, representing its latest trading iteration
     * @return good2correntstate The current state of the second good, representing its latest trading iteration
     * @notice This function is a view function that:
     * - Returns the current trading iteration (state) for both goods
     * - Useful for checking the latest trading status of a pair of goods
     * - Can be used to verify if goods are in sync for trading operations
     * @custom:security This is a view function with no state modifications
     * @custom:security Returns 0 if either good address is not registered
     */
    /// @inheritdoc I_TTSwap_Market
    function getRecentGoodState(
        address good1,
        address good2
    )
        external
        view
        override
        returns (uint256 good1currentstate, uint256 good2currentstate)
    {
        // return (goods[good1].currentState, goods[good2].currentState);
        return (
            toTTSwapUINT256(
                goods[good1].investState.amount1(),
                goods[good1].currentState.amount1()
            ),
            toTTSwapUINT256(
                goods[good2].investState.amount1(),
                goods[good2].currentState.amount1()
            )
        );
    }

    /// @notice Retrieves the current state of a proof
    /// @param proofid The ID of the proof to query
    /// @return proofstate The current state of the proof,
    ///  currentgood The current good associated with the proof
    ///  valuegood The value good associated with the proof
    ///  shares normal good shares, value good shares
    ///  state Total value, Total actual value
    ///  invest normal good virtual quantity, normal good actual quantity
    ///  valueinvest value good virtual quantity, value good actual quantity
    /// @inheritdoc I_TTSwap_Market
    function getProofState(
        uint256 proofid
    ) external view override returns (S_ProofState memory) {
        return proofs[proofid];
    }

    /// @notice Retrieves the current state of a good
    /// @param good The address of the good to query
    /// @return goodstate The current state of the good,
    ///  goodConfig Configuration of the good, check goodconfig.sol or whitepaper for details
    ///  owner Creator of the good
    ///  currentState Present investQuantity, CurrentQuantity
    ///  investState Shares, value
    /// @inheritdoc I_TTSwap_Market
    function getGoodState(
        address good
    ) external view override returns (S_GoodTmpState memory) {
        return
            S_GoodTmpState(
                goods[good].goodConfig,
                goods[good].owner,
                goods[good].currentState,
                goods[good].investState
            );
    }

    /// @notice Updates a good's configuration
    /// @param _goodid The ID of the good
    /// @param _goodConfig The new configuration
    /// @return Success status
    /// @inheritdoc I_TTSwap_Market
    function updateGoodConfig(
        address _goodid,
        uint256 _goodConfig
    ) external override returns (bool) {
        if (msg.sender != goods[_goodid].owner) revert TTSwapError(20);
        goods[_goodid].updateGoodConfig(_goodConfig);
        emit e_updateGoodConfig(_goodid, goods[_goodid].goodConfig);
        return true;
    }

    /// @param _goodid The ID of the good
    /// @param _goodConfig The new configuration
    /// @return Success status
    /// @inheritdoc I_TTSwap_Market
    function modifyGoodConfig(
        address _goodid,
        uint256 _goodConfig
    ) external override onlyMarketor returns (bool) {
        if(!_goodConfig.checkGoodConfig()) revert TTSwapError(24);
        goods[_goodid].modifyGoodConfig(_goodConfig);
        emit e_modifyGoodConfig(_goodid, goods[_goodid].goodConfig);
        return true;
    }

    /// @param _goodid The ID of the good
    /// @param _goodConfig The new configuration
    /// @return Success status
    /// @inheritdoc I_TTSwap_Market
    function modifyGoodCoreConfig(
        address _goodid,
        uint256 _goodConfig
    ) external override onlyMarketadmin returns (bool) {
        goods[_goodid].modifyGoodCoreConfig(_goodConfig);
        emit e_modifyGoodConfig(_goodid, goods[_goodid].goodConfig);
        return true;
    }

    function lockGood(address _goodid) external override  {
        require(TTS_CONTRACT.userConfig(msg.sender).isMarketManager()||goods[_goodid].owner==msg.sender);
        goods[_goodid].lockGood();
        emit e_updateGoodConfig(_goodid, goods[_goodid].goodConfig);
    }

    /// @notice Changes the owner of a good
    /// @param _goodid The ID of the good
    /// @param _to The new owner's address
    /// @inheritdoc I_TTSwap_Market
    function changeGoodOwner(
        address _goodid,
        address _to
    ) external override onlyMarketor {
        goods[_goodid].owner = _to;
        emit e_changegoodowner(_goodid, _to);
    }

    /// @notice Collects commission for specified goods
    /// @param _goodid Array of good IDs
    /// @inheritdoc I_TTSwap_Market
    function collectCommission(
        address[] calldata _goodid
    ) external override noReentrant {
        address recipent = TTS_CONTRACT.userConfig(msg.sender).isMarketAdmin()
            ? address(0)
            : msg.sender;
        if (_goodid.length > 100) revert TTSwapError(21);
        uint256[] memory commissionamount = new uint256[](_goodid.length);
        for (uint256 i = 0; i < _goodid.length; i++) {
            commissionamount[i] = goods[_goodid[i]].commission[recipent];
            if (commissionamount[i] > 2) {
                commissionamount[i] = commissionamount[i] - 1;
                goods[_goodid[i]].commission[recipent] = 1;
                _goodid[i].safeTransfer(msg.sender, commissionamount[i]);
            }
        }
        emit e_collectcommission(_goodid, commissionamount);
    }

    /**
     * @dev Queries commission amounts for multiple goods for a specific recipient
     * @param _goodid Array of good addresses to query commission for
     * @param _recipent The address to check commission amounts for
     * @return feeamount Array of commission amounts corresponding to each good
     * @notice This function:
     * - Returns commission amounts for up to 100 goods in a single call
     * - Each amount represents the commission available for the recipient
     * - Returns 0 for goods where no commission is available
     * - Maintains gas efficiency by using a fixed array size
     * @custom:security Reverts if more than 100 goods are queried
     * @custom:security View function, does not modify state
     */
    /// @inheritdoc I_TTSwap_Market
    function queryCommission(
        address[] calldata _goodid,
        address _recipent
    ) external view override returns (uint256[] memory) {
        if (_goodid.length > 100) revert TTSwapError(21);
        uint256[] memory feeamount = new uint256[](_goodid.length);
        for (uint256 i = 0; i < _goodid.length; i++) {
            feeamount[i] = goods[_goodid[i]].commission[_recipent];
        }
        return feeamount;
    }

    /**
     * @dev Adds welfare funds to a good's fee pool
     * @param goodid The address of the good to receive welfare
     * @param welfare The amount of tokens to add as welfare
     * @param data Additional data for token transfer
     * @notice This function:
     * - Allows anyone to contribute additional funds to a good's fee pool
     * - Increases the good's feeQuantityState by the welfare amount
     * - Transfers tokens from the sender to the good
     * - Emits an event with the welfare contribution details
     * @custom:security Protected by noReentrant modifier
     * @custom:security Checks for overflow in feeQuantityState
     */
    /// @inheritdoc I_TTSwap_Market
    function goodWelfare(
        address goodid,
        uint128 welfare,
        bytes calldata data
    ) external payable override noReentrant msgValue {
        if (goods[goodid].currentState.amount0() + welfare > 2 ** 109) {
            revert TTSwapError(18);
        }
        goodid.transferFrom(msg.sender, welfare, data);
        goods[goodid].currentState = add(
            goods[goodid].currentState,
            toTTSwapUINT256(uint128(welfare), uint128(welfare))
        );
        emit e_goodWelfare(goodid, welfare);
    }

    function removeSecurityKeeper() external onlyMarketadmin {
        if (securitykeeper != msg.sender) revert TTSwapError(22);
        securitykeeper = address(0);
    }

    function securityKeeper(address erc20) external noReentrant {
        if (securitykeeper != msg.sender) revert TTSwapError(22);
        if (!goods[erc20].goodConfig.isFreeze()) revert TTSwapError(34);
        uint256 amount = erc20.balanceof(address(this));
        erc20.safeTransfer(msg.sender, amount);
    }
}
"
    },
    "src/interfaces/I_TTSwap_Token.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.29;

/// @title Investment Proof Interface
/// @notice Contains a series of interfaces for goods
interface I_TTSwap_Token {
    /// @notice Emitted when environment variables are set
    /// @param marketcontract The address of the market contract
    event e_setenv(address marketcontract);

    /// @notice Emitted when user config is updated
    /// @param user The address of the user
    /// @param config The new config value
    event e_updateUserConfig(address user, uint256 config);

    /// @notice Emitted when a referral relationship is added
    /// @param user The address of the user being referred
    event e_addreferral(address user, address referal);

    /// @notice Emitted when minting is added
    /// @param recipient The address receiving the minted tokens
    /// @param leftamount The remaining amount to be minted
    /// @param metric The metric used for minting
    /// @param chips The number of chips
    event e_addShare(
        address recipient,
        uint128 leftamount,
        uint120 metric,
        uint8 chips
    );

    /// @notice Emitted when minting is burned
    /// @param owner The index of the minting operation being burned
    event e_burnShare(address owner);

    /// @notice Emitted when DAO minting occurs
    /// @param mintamount The amount being minted
    /// @param owner The index of the minting operation
    event e_shareMint(uint128 mintamount, address owner);

    /// @notice Emitted during a public sale
    /// @param usdtamount The amount of USDT involved
    /// @param ttsamount The amount of TTS involved
    event e_publicsell(uint256 usdtamount, uint256 ttsamount);

    /// @notice Emitted when chain stake is synchronized
    /// @param chain The chain ID
    /// @param poolasset The pool asset value
    /// @param proofstate  The value of the pool
    //first 128 bit proofvalue,last 128 bit proofconstruct
    event e_syncChainStake(uint32 chain, uint128 poolasset, uint256 proofstate);

    /// @notice Emitted when unstaking occurs
    /// @param recipient The address receiving the unstaked tokens
    /// @param proofvalue first 128 bit proofvalue,last 128 bit poolcontruct
    /// @param unstakestate The state after unstaking
    /// @param stakestate The state of the stake
    /// @param poolstate The state of the pool
    event e_stakeinfo(
        address recipient,
        uint256 proofvalue,
        uint256 unstakestate,
        uint256 stakestate,
        uint256 poolstate
    );
    /// @notice Emitted when the pool state is updated
    /// @param poolstate The new state of the pool
    event e_updatepool(uint256 poolstate);
    /// @notice Emitted when the pool state is updated
    /// @param ttsconfig The new state of the pool
    event e_updatettsconfig(uint256 ttsconfig);

    /**
     * @dev Returns the share information for a given user address.
     * @param user The address to query for share information.
     * @return The s_share struct containing the user's share details.
     */
    function usershares(address user) external view returns (s_share memory);

    /**
     * @dev Returns the current staking state.
     * @return The staking state as a uint256 value.
     */
    function stakestate() external view returns (uint256);

    /**
     * @dev Returns the current pool state.
     * @return The pool state as a uint256 value.
     */
    function poolstate() external view returns (uint256);

    /**
     * @dev Returns the TTS token configuration value.
     * @return The configuration as a uint256 value.
     */
    function ttstokenconfig() external view returns (uint256);

    /**
     * @dev Returns the amount of left share available for minting.
     * @return The left share as a uint128 value.
     */
    function left_share() external view returns (uint128);

    /**
     * @dev Returns the stake proof information for a given index.
     * @param index The index to query for stake proof information.
     * @return The s_proof struct containing the stake proof details.
     */
    function stakeproofinfo(uint256 index) external view returns (s_proof memory);

    /**
     * @dev Sets the trading volume ratio for the protocol.
     * @param _ratio The new ratio value (max 10000).
     */
    function setRatio(uint256 _ratio) external;

    /**
     * @dev Grants or revokes DAO admin privileges to a recipient address.
     * @param _recipient The address to grant or revoke DAO admin rights.
     * @param result Boolean indicating whether to grant (true) or revoke (false) the privilege.
     */
    function setDAOAdmin(address _recipient, bool result) external;

    /**
     * @dev Grants or revokes Token admin privileges to a recipient address.
     * @param _recipient The address to grant or revoke Token admin rights.
     * @param result Boolean indicating whether to grant (true) or revoke (false) the privilege.
     */
    function setTokenAdmin(address _recipient, bool result) external;

    /**
     * @dev Grants or revokes Token manager privileges to a recipient address.
     * @param _recipient The address to grant or revoke Token manager rights.
     * @param result Boolean indicating whether to grant (true) or revoke (false) the privilege.
     */
    function setTokenManager(address _recipient, bool result) external;

    /**
     * @dev Grants or revokes permission to call mintTTS to a recipient address.
     * @param _recipient The address to grant or revoke permission.
     * @param result Boolean indicating whether to grant (true) or revoke (false) the privilege.
     */
    function setCallMintTTS(address _recipient, bool result) external;

    /**
     * @dev Grants or revokes Market admin privileges to a recipient address.
     * @param _recipient The address to grant or revoke Market admin rights.
     * @param result Boolean indicating whether to grant (true) or revoke (false) the privilege.
     */
    function setMarketAdmin(address _recipient, bool result) external;

    /**
     * @dev Grants or revokes Market manager privileges to a recipient address.
     * @param _recipient The address to grant or revoke Market manager rights.
     * @param result Boolean indicating whether to grant (true) or revoke (false) the privilege.
     */
    function setMarketManager(address _recipient, bool result) external;

    /**
     * @dev Grants or revokes Stake admin privileges to a recipient address.
     * @param _recipient The address to grant or revoke Stake admin rights.
     * @param result Boolean indicating whether to grant (true) or revoke (false) the privilege.
     */
    function setStakeAdmin(address _recipient, bool result) external;

    /**
     * @dev Grants or revokes Stake manager privileges to a recipient address.
     * @param _recipient The address to grant or revoke Stake manager rights.
     * @param result Boolean indicating whether to grant (true) or revoke (false) the privilege.
     */
    function setStakeManager(address _recipient, bool result) external;

    /**
     * @dev Sets or unsets a ban on a recipient address, restricting their access.
     * @param _recipient The address to ban or unban.
     * @param result Boolean indicating whether to ban (true) or unban (false) the address.
     */
    function setBan(address _recipient, bool result) external;

    /**
     * @dev  Returns the amount of TTS available for public sale
     * @return _publicsell Returns the amount of TTS available for public sale
     */
    function publicsell() external view returns (uint128 _publicsell);

    /**
     * @dev Returns the authorization level for a given address
     * @param recipent user's address
     * @return _auth Returns the authorization level
     */
    function userConfig(address recipent) external view returns (uint256 _auth);

    /**
     * @dev Sets the environment variables for normal good ID, value good ID, and market contract address
     * @param _marketcontract The address of the market contract
     */
    function setEnv(address _marketcontract) external; 
    /**
     * @dev Adds a new mint share to the contract
     * @param _share The share structure containing recipient, amount, metric, and chips
     * @notice Only callable on the main chain by the DAO admin
     * @notice Reduces the left_share by the amount in _share
     * @notice Increments the shares_index and adds the new share to the shares mapping
     * @notice Emits an e_addShare event with the share details
     */
    function addShare(s_share calldata _share, address owner) external;
    /**
     * @dev  Burns the share at the specified index
     * @param owner owner of share
     */
    function burnShare(address owner) external;
    /**
     * @dev  Mints a share at the specified
     */
    function shareMint() external;
    /**
     * @dev how much cost to buy tts
     * @param usdtamount usdt amount
     */
    function publicSell(uint256 usdtamount, bytes calldata data) external;
    /**
     * @dev  Withdraws the specified amount from the public sale to the recipient
     * @param amount admin tranfer public sell to another address
     * @param recipent user's address
     */
    function withdrawPublicSell(uint256 amount, address recipent) external;

    /**
     * @dev Burns the specified value of tokens from the given account
     * @param value the amount will be burned
     */
    function burn(uint256 value) external;

    /// @notice Add a referral relationship
    /// @param user The address of the user being referred
    /// @param referral The address of the referrer
    function setReferral(address user, address referral) external;

    /// @notice Stake tokens
    /// @param staker The address of the staker
    /// @param proofvalue The proof value for the stake
    /// @return construct The construct value after staking
    function stake(
        address staker,
        uint128 proofvalue
    ) external returns (uint128 construct);

    /// @notice Unstake tokens
    /// @param staker The address of the staker
    /// @param proofvalue The proof value for unstaking
    function unstake(address staker, uint128 proofvalue) external;

    /// @notice Get the DAO admin and referral for a customer
    /// @param _customer The address of the customer
    /// @return referral The address of the referrer
    function getreferral(
        address _customer
    ) external view returns (address referral);

    /**
     * @dev Permits a share to be transferred
     * @param _share The share structure containing recipient, amount, metric, and chips
     * @param dealline The deadline for the share transfer
     * @param signature The signature of the share transfer
     * @param signer The address of the signer
     */
    function permitShare(
        s_share memory _share,
        uint128 dealline,
        bytes calldata signature,
        address signer
    ) external;

    /**
     * @dev Calculates the hash of a share transfer
     * @param _share The share structure containing recipient, amount, metric, and chips
     * @param owner The address of the owner
     * @param leftamount The amount of left share
     * @param deadline The deadline for the share transfer
     */
    function shareHash(
        s_share memory _share,
        address owner,
        uint128 leftamount,
        uint128 deadline,
        uint256 nonce
    ) external pure returns (bytes32);
}

/// @notice Struct for share information
/// @dev Contains information about a share, including the amount of left to unlock, the metric, and the chips
struct s_share {
    uint128 leftamount; // unlock amount
    uint120 metric; //last unlock's metric
    uint8 chips; // define the share's chips, and every time unlock one chips
}

/// @notice Struct for proof information
/// @dev Contains information about a proof, including the contract address and the state
struct s_proof {
    address fromcontract; // from which contract
    uint256 proofstate; // stake's state  amount0 value 128 construct asset
}
"
    },
    "src/interfaces/IMulticall_v4.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/// @title IMulticall_v4
/// @notice Interface for the Multicall_v4 contract
interface IMulticall_v4 {
    /// @notice Call multiple functions in the current contract and return the data from all of them if they all succeed
    /// @dev The `msg.value` is passed onto all subcalls, even if a previous subcall has consumed the ether.
    /// Subcalls can instead use `address(this).value` to see the available ETH, and consume it using {value: x}.
    /// @param data The encoded function data for each of the calls to make to this contract
    /// @return results The results from each of the calls passed in via data
    function multicall(bytes[] calldata data) external payable returns (bytes[] memory results);
}
"
    },
    "src/libraries/L_TTSwapUINT256.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.29;

using L_TTSwapUINT256Library for uint256;
/// @notice Converts two uint128 values into a T_BalanceUINT256
/// @param _amount0 The first 128-bit amount
/// @param _amount1 The second 128-bit amount
/// @return balanceDelta The resulting T_BalanceUINT256

function toTTSwapUINT256(uint128 _amount0, uint128 _amount1) pure returns (uint256 balanceDelta) {
    assembly ("memory-safe") {
        balanceDelta :=
            or(shl(128, _amount0), and(0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff, _amount1))
    }
}

/// @notice Adds two T_BalanceUINT256 values
/// @param a The first T_BalanceUINT256
/// @param b The second T_BalanceUINT256
/// @return The sum of a and b as a T_BalanceUINT256
function add(uint256 a, uint256 b) pure returns (uint256) {
    uint256 res0;
    uint256 res1;
    uint256 a0;
    uint256 a1;
    uint256 b0;
    uint256 b1;
    assembly ("memory-safe") {
         a0 := shr(128, a)
         a1 := and(0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff, a)
         b0 := shr(128, b)
         b1 := and(0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff, b)
        res0 := add(a0, b0)
        res1 := add(a1, b1)
    }
    require(res0 >= a0 && res0 >= b0 && res1 >= a1 && res1 >= b1 && res1 <type(uint128).max && res0 <type(uint128).max, "TTSwapUINT256: add overflow");
    return (res0<<128)+res1;
}


/// @notice Subtracts two T_BalanceUINT256 values
/// @param a The first T_BalanceUINT256
/// @param b The second T_BalanceUINT256
/// @return The difference of a and b as a T_BalanceUINT256
function sub(uint256 a, uint256 b) pure returns (uint256) {
    uint256 res0;
    uint256 res1;
    uint256 a0;
    uint256 a1;
    uint256 b0;
    uint256 b1;
    unchecked{
    assembly ("memory-safe") {
         a0 := shr(128, a)
         a1 := and(0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff, a)
         b0 := shr(128, b)
         b1 := and(0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff, b)
        res0 := sub(a0, b0)
        res1 := sub(a1, b1)
    }}
    require(res0 <=a0 && res1<=a1 &&a1>=b1 && a0>=b0, "TTSwapUINT256: sub overflow");
    return (res0<<128)+res1;
}

/// @notice Adds the first components and subtracts the second components of two T_BalanceUINT256 values
/// @param a The first T_BalanceUINT256
/// @param b The second T_BalanceUINT256
/// @return The result of (a0 + b0, a1 - b1) as a T_BalanceUINT256
function addsub(uint256 a, uint256 b) pure returns (uint256) {
    uint256 res0;
    uint256 res1;
    uint256 a0;
    uint256 a1;
    uint256 b0;
    uint256 b1;
    unchecked{
    assembly ("memory-safe") {
         a0 := shr(128, a)
         a1 := and(0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff, a)
         b0 := shr(128, b)
         b1 := and(0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff, b)
        res0 := add(a0, b0)
        res1 := sub(a1, b1)
    }}
    require(res0 >=a0 && res0>=b0 && res1<=a1 && a1>=b1 && res0<type(uint128).max , "TTSwapUINT256: addsub overflow");
    return (res0<<128)+res1;
}

/// @notice Subtracts the first components and adds the second components of two T_BalanceUINT256 values
/// @param a The first T_BalanceUINT256
/// @param b The second T_BalanceUINT256
/// @return The result of (a0 - b0, a1 + b1) as a T_BalanceUINT256
function subadd(uint256 a, uint256 b) pure returns (uint256) {
    uint256 res0;
    uint256 res1;
    uint256 a0;
    uint256 a1;
    uint256 b0;
    uint256 b1;
    unchecked{
    assembly ("memory-safe") {
        a0 := sar(128, a)
        a1 := and(0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff, a)
        b0 := sar(128, b)
        b1 := and(0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff, b)
        res0 := sub(a0, b0)
        res1 := add(a1, b1)
    }}

    require(res1 >=a1 && res1>=b1 && res0<=a0 && a0>=b0 && res1<type(uint128).max , "TTSwapUINT256: subadd overflow");
    return (res0<<128)+res1;
}

/// @notice Safely converts a uint256 to a uint128
/// @param a The uint256 value to convert
/// @return b converted uint128 value, or 0 if overflow
function toUint128(uint256 a) pure returns (uint128 b) {
    b=uint128(a);
    require(a==uint256(b) , "TTSwapUINT256: toUint128 overflow");
}

/// @notice Compares the prices of three T_BalanceUINT256 values
/// @param a The first T_BalanceUINT256
/// @param b The second T_BalanceUINT256
/// @param c The third T_BalanceUINT256
/// @return True if the price of a is lower than the prices of b and c, false otherwise
function lowerprice(uint256 a, uint256 b, uint256 c) pure returns (bool) {
    return uint256(a.amount0()) * uint256(b.amount1()) * uint256(c.amount1())
        > uint256(a.amount1()) * uint256(b.amount0()) * uint256(c.amount0()) ? true : false;
}

/// @notice Performs a multiplication followed by a division
/// @param config The multiplicand
/// @param amount The multiplier
/// @param domitor The divisor
/// @return a The result as a uint128
function mulDiv(uint256 config, uint256 amount, uint256 domitor) pure returns (uint128 a) {
    uint256 result;
    unchecked {
        assembly {
            config := mul(config, amount)
            result := div(config, domitor)
        }
    }
    return toUint128(result);
}

/// @title L_TTSwapUINT256Library
/// @notice A library for operations on T_BalanceUINT256
library L_TTSwapUINT256Library {
    /// @notice Extracts the first 128-bit amount from a T_BalanceUINT256
    /// @param balanceDelta The T_BalanceUINT256 to extract from
    /// @return _amount0 The extracted first 128-bit amount
    function amount0(uint256 balanceDelta) internal pure returns (uint128 _amount0) {
        assembly {
            _amount0 := shr(128, balanceDelta)
        }
    }

    /// @notice Extracts the second 128-bit amount from a T_BalanceUINT256
    /// @param balanceDelta The T_BalanceUINT256 to extract from
    /// @return _amount1 The extracted second 128-bit amount
    function amount1(uint256 balanceDelta) internal pure returns (uint128 _amount1) {
        assembly {
            _amount1 := balanceDelta
        }
    }

    /// @notice Extracts the first and second 128-bit amounts from a T_BalanceUINT256
    /// @param balanceDelta The T_BalanceUINT256 to extract from
    /// @return _amount0 The extracted first 128-bit amount
    /// @return _amount1 The extracted second 128-bit amount
    function amount01(uint256 balanceDelta) internal pure returns (uint128 _amount0,uint128 _amount1) {
        assembly {
            _amount0 := shr(128, balanceDelta)
            _amount1 := balanceDelta
        }
    }

    /// @notice Calculates amount0 based on a given amount1 and the ratio in balanceDelta
    /// @param balanceDelta The T_BalanceUINT256 containing the ratio
    /// @param amount1delta The amount1 to base the calculation on
    /// @return _amount0 The calculated amount0
    function getamount0fromamount1(uint256 balanceDelta, uint128 amount1delta)
        internal
        pure
        returns (uint128 _amount0)
    {
        return mulDiv(balanceDelta.amount0(), amount1delta, balanceDelta.amount1());
    }

    /// @notice Calculates amount1 based on a given amount0 and the ratio in balanceDelta
    /// @param balanceDelta The T_BalanceUINT256 containing the ratio
    /// @param amount0delta The amount0 to base the calculation on
    /// @return _amount1 The calculated amount1
    function getamount1fromamount0(uint256 balanceDelta

Tags:
ERC20, Multisig, Burnable, Swap, Liquidity, Staking, Voting, Upgradeable, Multi-Signature, Factory|addr:0x29d57620e7af733c43679818226e62ae0f49db5b|verified:true|block:23580651|tx:0x408497bf090654e97a684c0065e06270dae1755af7f9070642533e22276a9f8b|first_check:1760519389

Submitted on: 2025-10-15 11:09:51

Comments

Log in to comment.

No comments yet.