S Price: $0.605863 (-18.98%)

Token

Vote-Escrowed STTX (veSTTX)

Overview

Max Total Supply

14,828,494,520.47551219292611186 veSTTX

Holders

268

Market

Price

$0.00 @ 0.000000 S

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
7 veSTTX

Value
$0.00
0xc0ad5d21ff19a4e85b016bfd53ced8842995c151
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Contract Source Code Verified (Exact Match)

Contract Name:
VoteEscrowedSTTX

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
No with 200 runs

Other Settings:
paris EvmVersion
File 1 of 33 : VoteEscrowedSTTX.sol
// SPDX-License-Identifier: MIT
/*
                 ___________________________________  ___ 
___  __  ____   /   _____/\__    ___/\__    ___/\   \/  / 
\  \/ /_/ __ \  \_____  \   |    |     |    |    \     /  
 \   / \  ___/  /        \  |    |     |    |    /     \  
  \_/   \___  >/_______  /  |____|     |____|   /___/\  \ 
            \/         \/                             \_/                                                            
*/

pragma solidity >=0.8.24 <0.9.0;

import {Ownable} from "./abstract/Ownable.sol";
import {ReentrancyGuard} from "./abstract/ReentrancyGuard.sol";
import {IBaseContracts} from "./interface/IBaseContracts.sol";
import {IERC20Custom} from "./interface/IERC20Custom.sol";
import {IERC20TokenRebase} from "./interface/IERC20TokenRebase.sol";
import {IVoteEscrowedSTTX} from "./interface/IVoteEscrowedSTTX.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IERC20 as IERC20Safe} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

/**
 * @title VoteEscrowedSTTX
 * @dev Time-locked governance token
 * @notice Lock and vote manager
 */
contract VoteEscrowedSTTX is
    Ownable,
    ReentrancyGuard,
    IERC20Custom,
    IVoteEscrowedSTTX
{
    /*//////////////////////////////////////////////////////////////
                        TOKEN CONFIGURATION
    //////////////////////////////////////////////////////////////*/
    /// @notice Base STTX token contract
    IERC20TokenRebase public immutable sttx;
    /// @notice Token name
    string private _name;
    /// @notice Token symbol
    string private _symbol;
    /// @notice Token decimal places
    /// @dev Fixed at 18 decimals
    uint8 private constant DECIMALS = 18;
    /*//////////////////////////////////////////////////////////////
                        TOKEN STATE TRACKING
    //////////////////////////////////////////////////////////////*/
    /// @notice Total supply of veSTTX tokens
    uint256 private _totalSupply;
    /// @notice User token balances
    /// @dev Tracks individual account balances
    mapping(address => uint256) private _balances;
    /// @notice Token spending allowances
    /// @dev Nested mapping of owner → spender → allowance
    mapping(address => mapping(address => uint256)) private _allowances;
    /*//////////////////////////////////////////////////////////////
                        WITHDRAWAL CONFIGURATION
    //////////////////////////////////////////////////////////////*/
    /// @notice Delay before withdrawal becomes available
    /// @dev Default: 7 days
    uint256 public withdrawalDelay = 7 days;
    /// @notice Window duration for completing withdrawal
    /// @dev Default: 21 hours
    uint256 public withdrawalWindow = 21 hours;
    /*//////////////////////////////////////////////////////////////
                        WITHDRAWAL STATE TRACKING
    //////////////////////////////////////////////////////////////*/
    /// @notice Pending withdrawal amounts per account
    mapping(address => uint256) public withdrawalAmounts;
    /// @notice Withdrawal timestamp for each account
    mapping(address => uint256) public withdrawalTimestamps;
    /// @notice Withdrawal slot tracking
    mapping(uint256 => uint256) public withdrawalSlots;
    /*//////////////////////////////////////////////////////////////
                        ACCESS CONTROL STATE
    //////////////////////////////////////////////////////////////*/
    /// @notice Mapping of approved token spenders
    /// @dev Allows controlled token spending
    mapping(address => bool) public approvedSpenders;
    /*//////////////////////////////////////////////////////////////
                            EVENTS
    //////////////////////////////////////////////////////////////*/
    /// @notice Emitted when a spender is approved
    event SpenderApproved(address indexed spender);
    /// @notice Emitted when a spender is revoked
    event SpenderRevoked(address indexed spender);
    /// @notice Emitted when withdrawal delay is decreased
    event WithdrawalDelayDecreased(uint256 newDelay);
    /// @notice Emitted when withdrawal window is increased
    event WithdrawalWindowIncreased(uint256 newWindow);
    /// @notice Emitted when a withdrawal is initiated
    event WithdrawalInitiated(
        address indexed account,
        uint256 amount,
        uint256 timestamp
    );
    /// @notice Emitted when a withdrawal is completed
    event WithdrawalCompleted(address indexed account, uint256 amount);
    /*//////////////////////////////////////////////////////////////
                            CUSTOM ERRORS
    //////////////////////////////////////////////////////////////*/
    /// @notice Thrown when a zero address is provided
    error ZeroAddress();
    /// @notice Thrown when a zero amount is provided
    error ZeroAmount();
    /// @notice Thrown when an invalid withdrawal delay is set
    error InvalidWithdrawalDelay();
    /// @notice Thrown when an invalid withdrawal window is set
    error InvalidWithdrawalWindow();
    /// @notice Thrown when an invalid sender is detected
    error InvalidSender(address sender);
    /// @notice Thrown when an invalid receiver is detected
    error InvalidReceiver(address receiver);
    /// @notice Thrown when an invalid approver is detected
    error InvalidApprover(address approver);
    /// @notice Thrown when an invalid spender is detected
    error InvalidSpender(address spender);
    /// @notice Thrown when balance is insufficient
    error InsufficientBalance();
    /// @notice Thrown when allowance is insufficient
    error InsufficientAllowance(
        address spender,
        uint256 allowance,
        uint256 needed
    );
    /// @notice Thrown when a spender is not authorized
    error SpenderNotAuthorized();
    /// @notice Thrown when no withdrawal is initiated
    error WithdrawalNotInitiated();
    /// @notice Thrown when withdrawal window is not open
    error WithdrawalWindowNotOpenYet();
    /// @notice Thrown when withdrawal window is closed
    error WithdrawalWindowAlreadyClosed();

    /*//////////////////////////////////////////////////////////////
                            CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Initializes the veSTTX token
     * @param name_ Token name
     * @param symbol_ Token symbol
     * @param baseContracts_ BaseContracts instance for protocol integration
     *
     * Requirements:
     * · STTX contract address must be non-zero
     *
     * Effects:
     * · Sets token metadata
     * · Sets base STTX token reference
     */
    constructor(
        string memory name_,
        string memory symbol_,
        IBaseContracts baseContracts_
    ) {
        _ensureNonzeroAddress(address(baseContracts_));
        sttx = baseContracts_.sttx();
        _ensureNonzeroAddress(address(sttx));
        _name = name_;
        _symbol = symbol_;
    }

    /*//////////////////////////////////////////////////////////////
                        EXTERNAL FUNCTIONS · ACCESS CONTROL
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Approves a spender to spend tokens on behalf of the owner
     * @param spender Address of the approved spender
     *
     * Requirements:
     * · Only callable by contract owner
     * · Validates non-zero address for spender
     *
     * Effects:
     * · Sets spender approval
     */
    function approveSpender(address spender) external onlyOwner {
        _ensureNonzeroAddress(spender);
        approvedSpenders[spender] = true;
        emit SpenderApproved(spender);
    }

    /**
     * @notice Revokes a spender's approval to spend tokens on behalf of the owner
     * @param spender Address of the revoked spender
     *
     * Requirements:
     * · Only callable by contract owner
     * · Validates non-zero address for spender
     *
     * Effects:
     * · Sets spender approval
     */
    function revokeSpender(address spender) external onlyOwner {
        _ensureNonzeroAddress(spender);
        approvedSpenders[spender] = false;
        emit SpenderRevoked(spender);
    }

    /*//////////////////////////////////////////////////////////////
                        EXTERNAL FUNCTIONS · WITHDRAWAL SETTINGS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Decreases the withdrawal delay
     * @param newDelay New withdrawal delay
     *
     * Requirements:
     * · Only callable by contract owner
     * · New delay must be less than the current delay
     *
     * Effects:
     * · Sets the new withdrawal delay
     */
    function decreaseWithdrawalDelay(uint256 newDelay) external onlyOwner {
        if (newDelay >= withdrawalDelay) revert InvalidWithdrawalDelay();
        withdrawalDelay = newDelay;
        emit WithdrawalDelayDecreased(newDelay);
    }

    /**
     * @notice Increases the withdrawal window
     * @param newWindow New withdrawal window
     *
     * Requirements:
     * · Only callable by contract owner
     * · New window must be greater than the current window
     *
     * Effects:
     * · Sets the new withdrawal window
     */
    function increaseWithdrawalWindow(uint256 newWindow) external onlyOwner {
        if (newWindow <= withdrawalWindow) revert InvalidWithdrawalWindow();
        withdrawalWindow = newWindow;
        emit WithdrawalWindowIncreased(newWindow);
    }

    /*//////////////////////////////////////////////////////////////
                        EXTERNAL FUNCTIONS · CORE OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Deposits tokens into the contract
     * @param to Address to deposit tokens to
     * @param amount Amount of tokens to deposit
     *
     * Requirements:
     * · To address must be non-zero
     * · Amount must be non-zero
     *
     * Effects:
     * · Increases the to address's balance
     * · Increases the total supply
     * · Transfers tokens from the sender to the contract
     */
    function deposit(address to, uint256 amount) external nonReentrant {
        _ensureNonzeroAddress(to);
        _ensureNonzeroAmount(amount);
        _balances[to] += amount;
        _totalSupply += amount;
        SafeERC20.safeTransferFrom(
            IERC20Safe(address(sttx)),
            _msgSender(),
            address(this),
            amount
        );
        emit Transfer(address(0), to, amount);
    }

    /**
     * @notice Initiates a withdrawal
     * @param amount Amount of tokens to withdraw
     *
     * Requirements:
     * · Amount must be non-zero
     * · Amount must be less than or equal to the sender's balance
     *
     * Effects:
     * · Decreases the sender's balance
     * · Decreases the total supply
     * · Sets the withdrawal timestamp and amount
     */
    function beginWithdrawal(uint256 amount) external nonReentrant {
        _ensureNonzeroAmount(amount);
        address account = _msgSender();
        if (amount > balanceOf(account)) revert InsufficientBalance();
        _decreaseWithdrawalSlot(
            withdrawalTimestamps[account],
            withdrawalAmounts[account]
        );
        uint256 time = block.timestamp + withdrawalDelay;
        withdrawalTimestamps[account] = time;
        withdrawalAmounts[account] = amount;
        _increaseWithdrawalSlot(time, amount);
        emit WithdrawalInitiated(account, amount, time);
    }

    /**
     * @notice Completes a withdrawal
     *
     * Requirements:
     * · Withdrawal must be initiated
     * · Withdrawal window must be open
     * · Withdrawal amount must be less than or equal to the sender's balance
     *
     * Effects:
     * · Decreases the sender's balance
     * · Decreases the total supply
     * · Transfers tokens from the contract to the sender
     */
    function withdraw() external nonReentrant {
        address account = _msgSender();
        uint256 currentTime = block.timestamp;
        uint256 minTime = withdrawalTimestamps[account];
        if (minTime == 0) revert WithdrawalNotInitiated();
        if (currentTime <= minTime) revert WithdrawalWindowNotOpenYet();
        if (currentTime >= minTime + withdrawalWindow)
            revert WithdrawalWindowAlreadyClosed();
        uint256 amount = withdrawalAmounts[account];
        if (amount > balanceOf(account)) revert InsufficientBalance();
        _decreaseWithdrawalSlot(minTime, amount);
        withdrawalTimestamps[account] = 0;
        withdrawalAmounts[account] = 0;
        _balances[account] -= amount;
        _totalSupply -= amount;
        sttx.rebase();
        SafeERC20.safeTransfer(IERC20Safe(address(sttx)), account, amount);
        emit WithdrawalCompleted(account, amount);
        emit Transfer(account, address(0), amount);
    }

    /**
     * @notice Transfers tokens from one address to another
     * @param to Address to transfer tokens to
     * @param value Amount of tokens to transfer
     *
     * Requirements:
     * · To address must be non-zero
     * · Value must be non-zero
     *
     * Effects:
     * · Decreases the sender's balance
     * · Increases the to address's balance
     */
    function transfer(address to, uint256 value) external returns (bool) {
        _transfer(_msgSender(), to, value);
        return true;
    }

    /**
     * @notice Approves a spender to spend tokens on behalf of the owner
     * @param spender Address of the approved spender
     * @param value Amount of tokens to approve
     *
     * Requirements:
     * · Spender must be approved
     *
     * Effects:
     * · Sets the spender's allowance
     */
    function approve(address spender, uint256 value) external returns (bool) {
        if (!isApprovedSpender(spender)) revert SpenderNotAuthorized();
        _approve(_msgSender(), spender, value);
        return true;
    }

    /**
     * @notice Transfers tokens from one address to another using an allowance
     * @param from Address to transfer tokens from
     * @param to Address to transfer tokens to
     * @param value Amount of tokens to transfer
     *
     * Requirements:
     * · From address must be non-zero
     * · To address must be non-zero
     * · Value must be non-zero
     * · Spender must be approved
     *
     * Effects:
     * · Decreases the from address's balance
     * · Increases the to address's balance
     * · Decreases the spender's allowance
     */
    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, value);
        _transfer(from, to, value);
        return true;
    }

    /**
     * @notice Returns the token name
     *
     * Returns:
     * · Token name
     */
    function name() external view returns (string memory) {
        return _name;
    }

    /**
     * @notice Returns the token symbol
     *
     * Returns:
     * · Token symbol
     */
    function symbol() external view returns (string memory) {
        return _symbol;
    }

    /**
     * @notice Returns the total supply of tokens
     *
     * Returns:
     * · Total supply
     */
    function totalSupply() external view returns (uint256) {
        return _totalSupply;
    }

    /**
     * @notice Returns the withdrawal status for an account
     * @param account Address to retrieve the withdrawal status for
     *
     * Returns:
     * · Withdrawal amount
     * · Withdrawal timestamp
     * · Whether the withdrawal is withdrawable
     */
    function getWithdrawalStatus(
        address account
    )
        external
        view
        returns (uint256 amount, uint256 timestamp, bool isWithdrawable)
    {
        amount = withdrawalAmounts[account];
        timestamp = withdrawalTimestamps[account];
        uint256 currentTime = block.timestamp;
        isWithdrawable =
            timestamp != 0 &&
            currentTime > timestamp &&
            currentTime < timestamp + withdrawalWindow;
    }

    /**
     * @notice Returns the number of decimal places for the token
     *
     * Returns:
     * · Number of decimal places
     */
    function decimals() external pure returns (uint8) {
        return DECIMALS;
    }

    /**
     * @notice Returns the balance of an account
     * @param account Address to retrieve the balance for
     *
     * Returns:
     * · Balance
     */
    function balanceOf(address account) public view returns (uint256) {
        return _balances[account];
    }

    /**
     * @notice Returns the allowance for a spender
     * @param owner Address of the owner
     * @param spender Address of the spender
     *
     * Returns:
     * · Allowance
     */
    function allowance(
        address owner,
        address spender
    ) public view returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @notice Returns whether a spender is approved
     * @param spender Address of the spender
     *
     * Returns:
     * · Whether the spender is approved
     */
    function isApprovedSpender(address spender) public view returns (bool) {
        return approvedSpenders[spender];
    }

    /**
     * @notice Returns the withdrawal slot for a timestamp
     * @param time Timestamp to retrieve the withdrawal slot for
     *
     * Returns:
     * · Withdrawal slot
     */
    function getWithdrawalSlot(uint256 time) public view returns (uint256) {
        return time / withdrawalWindow;
    }

    /**
     * @notice Returns the total amount of tokens in the withdrawal slot
     * @param slot The withdrawal slot to check
     * @return Total amount of tokens in the slot
     */
    function getWithdrawalSlotAmount(
        uint256 slot
    ) public view returns (uint256) {
        return withdrawalSlots[slot];
    }

    /**
     * @notice Returns all withdrawal slots within a time range
     * @param startTime Start of the time range
     * @param endTime End of the time range
     * @return slots Array of slot numbers
     * @return amounts Array of amounts in each slot
     */
    function getWithdrawalSlotRange(
        uint256 startTime,
        uint256 endTime
    ) public view returns (uint256[] memory slots, uint256[] memory amounts) {
        uint256 startSlot = getWithdrawalSlot(startTime);
        uint256 endSlot = getWithdrawalSlot(endTime);
        uint256 slotCount = endSlot - startSlot + 1;
        slots = new uint256[](slotCount);
        amounts = new uint256[](slotCount);
        for (uint256 i = 0; i < slotCount; i++) {
            uint256 slot = startSlot + i;
            slots[i] = slot;
            amounts[i] = withdrawalSlots[slot];
        }
    }

    /**
     * @notice Returns the current withdrawal slot and the next slot
     * @return currentSlot Current withdrawal slot
     * @return currentAmount Amount in current slot
     * @return nextSlot Next withdrawal slot
     * @return nextAmount Amount in next slot
     */
    function getCurrentAndNextWithdrawalSlots()
        public
        view
        returns (
            uint256 currentSlot,
            uint256 currentAmount,
            uint256 nextSlot,
            uint256 nextAmount
        )
    {
        currentSlot = getWithdrawalSlot(block.timestamp);
        nextSlot = currentSlot + 1;
        currentAmount = withdrawalSlots[currentSlot];
        nextAmount = withdrawalSlots[nextSlot];
    }

    /*//////////////////////////////////////////////////////////////
                            PRIVATE FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Transfers tokens from one address to another
     * @param from Address to transfer tokens from
     * @param to Address to transfer tokens to
     * @param value Amount of tokens to transfer
     *
     * Effects:
     * · Decreases the from address's balance
     * · Increases the to address's balance
     * · Emits a Transfer event
     */
    function _transfer(address from, address to, uint256 value) private {
        if (from == address(0)) revert InvalidSender(address(0));
        if (to == address(0)) revert InvalidReceiver(address(0));
        _update(from, to, value);
    }

    /**
     * @notice Updates the balances of two addresses
     * @param from Address to decrease the balance of
     * @param to Address to increase the balance of
     * @param value Amount of tokens to transfer
     *
     * Effects:
     * · Decreases the from address's balance
     * · Increases the to address's balance
     * · Emits a Transfer event
     */
    function _update(address from, address to, uint256 value) private {
        if (from == address(0)) {
            _totalSupply += value;
        } else {
            uint256 fromBalance = _balances[from];
            if (fromBalance < value) {
                revert InsufficientBalance();
            }
            unchecked {
                _balances[from] = fromBalance - value;
            }
        }
        if (to == address(0)) {
            unchecked {
                _totalSupply -= value;
            }
        } else {
            unchecked {
                _balances[to] += value;
            }
        }
        emit Transfer(from, to, value);
    }

    /**
     * @notice Approves a spender to spend tokens on behalf of the owner
     * @param owner Address of the owner
     * @param spender Address of the approved spender
     * @param value Amount of tokens to approve
     *
     * Effects:
     * · Sets the spender's allowance
     */
    function _approve(address owner, address spender, uint256 value) private {
        _approve(owner, spender, value, true);
    }

    /**
     * @notice Approves a spender to spend tokens on behalf of the owner
     * @param owner Address of the owner
     * @param spender Address of the approved spender
     * @param value Amount of tokens to approve
     * @param emitEvent Whether to emit an Approval event
     *
     * Effects:
     * · Sets the spender's allowance
     */
    function _approve(
        address owner,
        address spender,
        uint256 value,
        bool emitEvent
    ) private {
        if (owner == address(0)) revert InvalidApprover(address(0));
        if (spender == address(0)) revert InvalidSpender(address(0));
        _allowances[owner][spender] = value;
        if (emitEvent) {
            emit Approval(owner, spender, value);
        }
    }

    /**
     * @notice Spends an allowance
     * @param owner Address of the owner
     * @param spender Address of the spender
     * @param value Amount of tokens to spend
     *
     * Effects:
     * · Decreases the spender's allowance
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 value
    ) private {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            if (currentAllowance < value) {
                revert InsufficientAllowance(spender, currentAllowance, value);
            }
            unchecked {
                _approve(owner, spender, currentAllowance - value, false);
            }
        }
    }

    /**
     * @notice Increases the withdrawal slot for a timestamp
     * @param time Timestamp to increase the withdrawal slot for
     * @param amount Amount of tokens to increase the withdrawal slot by
     *
     * Effects:
     * · Increases the withdrawal slot
     */
    function _increaseWithdrawalSlot(uint256 time, uint256 amount) private {
        uint256 slot = getWithdrawalSlot(time);
        withdrawalSlots[slot] += amount;
    }

    /**
     * @notice Decreases the withdrawal slot for a timestamp
     * @param time Timestamp to decrease the withdrawal slot for
     * @param amount Amount of tokens to decrease the withdrawal slot by
     *
     * Effects:
     * · Decreases the withdrawal slot
     */
    function _decreaseWithdrawalSlot(uint256 time, uint256 amount) private {
        if (time == 0 || amount == 0) return;
        uint256 slot = getWithdrawalSlot(time);
        if (amount > withdrawalSlots[slot]) {
            withdrawalSlots[slot] = 0;
            return;
        }
        withdrawalSlots[slot] -= amount;
    }

    // Validates that an address is not zero
    function _ensureNonzeroAddress(address addr) private pure {
        if (addr == address(0)) {
            revert ZeroAddress();
        }
    }

    // Validates that an amount is greater than zero
    function _ensureNonzeroAmount(uint256 amount) private pure {
        if (amount == 0) {
            revert ZeroAmount();
        }
    }
}

File 2 of 33 : IERC1363.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol)

pragma solidity ^0.8.20;

import {IERC20} from "./IERC20.sol";
import {IERC165} from "./IERC165.sol";

/**
 * @title IERC1363
 * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
 *
 * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract
 * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.
 */
interface IERC1363 is IERC20, IERC165 {
    /*
     * Note: the ERC-165 identifier for this interface is 0xb0202a11.
     * 0xb0202a11 ===
     *   bytes4(keccak256('transferAndCall(address,uint256)')) ^
     *   bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
     *   bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
     *   bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
     *   bytes4(keccak256('approveAndCall(address,uint256)')) ^
     *   bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
     */

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`
     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.
     * @param to The address which you want to transfer to.
     * @param value The amount of tokens to be transferred.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function transferAndCall(address to, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`
     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.
     * @param to The address which you want to transfer to.
     * @param value The amount of tokens to be transferred.
     * @param data Additional data with no specified format, sent in call to `to`.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.
     * @param from The address which you want to send tokens from.
     * @param to The address which you want to transfer to.
     * @param value The amount of tokens to be transferred.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function transferFromAndCall(address from, address to, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.
     * @param from The address which you want to send tokens from.
     * @param to The address which you want to transfer to.
     * @param value The amount of tokens to be transferred.
     * @param data Additional data with no specified format, sent in call to `to`.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
     * @param spender The address which will spend the funds.
     * @param value The amount of tokens to be spent.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function approveAndCall(address spender, uint256 value) external returns (bool);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
     * @param spender The address which will spend the funds.
     * @param value The amount of tokens to be spent.
     * @param data Additional data with no specified format, sent in call to `spender`.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}

File 3 of 33 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol)

pragma solidity ^0.8.20;

import {IERC165} from "../utils/introspection/IERC165.sol";

File 4 of 33 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../token/ERC20/IERC20.sol";

File 5 of 33 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC-20 standard as defined in the ERC.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the value of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 value) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}

File 6 of 33 : SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.2.0) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../IERC20.sol";
import {IERC1363} from "../../../interfaces/IERC1363.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC-20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    /**
     * @dev An operation with an ERC-20 token failed.
     */
    error SafeERC20FailedOperation(address token);

    /**
     * @dev Indicates a failed `decreaseAllowance` request.
     */
    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);

    /**
     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
    }

    /**
     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
     */
    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
    }

    /**
     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     *
     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
     * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
     */
    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 oldAllowance = token.allowance(address(this), spender);
        forceApprove(token, spender, oldAllowance + value);
    }

    /**
     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
     * value, non-reverting calls are assumed to be successful.
     *
     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
     * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
     */
    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
        unchecked {
            uint256 currentAllowance = token.allowance(address(this), spender);
            if (currentAllowance < requestedDecrease) {
                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
            }
            forceApprove(token, spender, currentAllowance - requestedDecrease);
        }
    }

    /**
     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
     * to be set to zero before setting it to a non-zero value, such as USDT.
     *
     * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function
     * only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being
     * set here.
     */
    function forceApprove(IERC20 token, address spender, uint256 value) internal {
        bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));

        if (!_callOptionalReturnBool(token, approvalCall)) {
            _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
            _callOptionalReturn(token, approvalCall);
        }
    }

    /**
     * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
     * targeting contracts.
     *
     * Reverts if the returned value is other than `true`.
     */
    function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
        if (to.code.length == 0) {
            safeTransfer(token, to, value);
        } else if (!token.transferAndCall(to, value, data)) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
     * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
     * targeting contracts.
     *
     * Reverts if the returned value is other than `true`.
     */
    function transferFromAndCallRelaxed(
        IERC1363 token,
        address from,
        address to,
        uint256 value,
        bytes memory data
    ) internal {
        if (to.code.length == 0) {
            safeTransferFrom(token, from, to, value);
        } else if (!token.transferFromAndCall(from, to, value, data)) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
     * targeting contracts.
     *
     * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
     * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
     * once without retrying, and relies on the returned value to be true.
     *
     * Reverts if the returned value is other than `true`.
     */
    function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
        if (to.code.length == 0) {
            forceApprove(token, to, value);
        } else if (!token.approveAndCall(to, value, data)) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     *
     * This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        uint256 returnSize;
        uint256 returnValue;
        assembly ("memory-safe") {
            let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
            // bubble errors
            if iszero(success) {
                let ptr := mload(0x40)
                returndatacopy(ptr, 0, returndatasize())
                revert(ptr, returndatasize())
            }
            returnSize := returndatasize()
            returnValue := mload(0)
        }

        if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     *
     * This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.
     */
    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
        bool success;
        uint256 returnSize;
        uint256 returnValue;
        assembly ("memory-safe") {
            success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
            returnSize := returndatasize()
            returnValue := mload(0)
        }
        return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);
    }
}

File 7 of 33 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC-165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[ERC].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 8 of 33 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

/**
 * @title Context
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, as when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 * @notice This contract is used through inheritance. It will make available the
 * modifier `_msgSender()`, which can be used to reference the account that
 * called a function within an implementing contract.
 */
abstract contract Context {
    /*//////////////////////////////////////////////////////////////
                            INTERNAL FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Gets the sender of the current call
     * @dev Provides a way to retrieve the message sender that supports meta-transactions
     * @return Sender address (msg.sender in the base implementation)
     */
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    /**
     * @notice Gets the complete calldata of the current call
     * @dev Provides a way to retrieve the message data that supports meta-transactions
     * @return Complete calldata bytes
     */
    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

    /**
     * @notice Gets the length of any context-specific suffix in the message data
     * @dev Used in meta-transaction implementations to account for additional data
     * @return Length of the context suffix (0 in the base implementation)
     */
    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

File 9 of 33 : Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

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

/**
 * @title Ownable
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 * @notice By default, the owner account will be the one that deploys the contract.
 * This can later be changed with {transferOwnership} and {renounceOwnership}.
 */
abstract contract Ownable is Context {
    /*//////////////////////////////////////////////////////////////
                            STATE VARIABLES
    //////////////////////////////////////////////////////////////*/
    /// @notice Address of the current owner
    address private _owner;
    /*//////////////////////////////////////////////////////////////
                                EVENTS
    //////////////////////////////////////////////////////////////*/
    /// @notice Emitted when ownership is transferred
    event OwnershipTransferred(
        address indexed previousOwner,
        address indexed newOwner
    );
    /*//////////////////////////////////////////////////////////////
                            CUSTOM ERRORS
    //////////////////////////////////////////////////////////////*/
    /// @notice Thrown when non-owner tries to call owner-only function
    error UnauthorizedAccount(address account);
    /// @notice Thrown when trying to transfer ownership to invalid address
    error InvalidOwner(address owner);
    /*//////////////////////////////////////////////////////////////
                                MODIFIERS
    //////////////////////////////////////////////////////////////*/
    /**
     * @dev Throws if called by any account other than the owner
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /*//////////////////////////////////////////////////////////////
                            CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/
    /**
     * @dev Initializes the contract setting the deployer as the initial owner
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /*//////////////////////////////////////////////////////////////
                            PUBLIC FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Leaves the contract without owner
     * @dev Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @notice Transfers ownership of the contract to a new account
     * @dev The new owner cannot be the zero address
     * @param newOwner The address that will become the new owner
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert InvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

    /*//////////////////////////////////////////////////////////////
                            VIEW FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Returns the address of the current owner
     * @return Current owner address
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /*//////////////////////////////////////////////////////////////
                            INTERNAL FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`)
     * Internal function without access restriction
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }

    /**
     * @dev Throws if the sender is not the owner
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert UnauthorizedAccount(_msgSender());
        }
    }
}

File 10 of 33 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

/**
 * @title ReentrancyGuard
 * @dev Contract module that helps prevent reentrant calls to a function
 * @notice This module is used through inheritance. It will make available the modifier
 * `nonReentrant`, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 */
abstract contract ReentrancyGuard {
    /*//////////////////////////////////////////////////////////////
                            STATE VARIABLES
    //////////////////////////////////////////////////////////////*/
    /// @notice Guard state constants
    uint256 private constant NOT_ENTERED = 1;
    uint256 private constant ENTERED = 2;
    /// @notice Current state of the guard
    uint256 private _status;
    /*//////////////////////////////////////////////////////////////
                            CUSTOM ERRORS
    //////////////////////////////////////////////////////////////*/
    error ReentrantCall();
    /*//////////////////////////////////////////////////////////////
                                MODIFIERS
    //////////////////////////////////////////////////////////////*/
    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    /*//////////////////////////////////////////////////////////////
                            CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Initializes the contract by setting the initial reentrancy guard state
     */
    constructor() {
        _status = NOT_ENTERED;
    }

    /*//////////////////////////////////////////////////////////////
                            VIEW FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Checks if a protected function is currently executing
     * @return True if the contract is in the entered state
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == ENTERED;
    }

    /*//////////////////////////////////////////////////////////////
                            PRIVATE FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @dev Sets guard state before protected function execution
     * @notice Reverts if a reentrant call is detected
     */
    function _nonReentrantBefore() private {
        if (_status == ENTERED) {
            revert ReentrantCall();
        }
        _status = ENTERED;
    }

    /**
     * @dev Resets guard state after protected function execution
     */
    function _nonReentrantAfter() private {
        _status = NOT_ENTERED;
    }
}

File 11 of 33 : IBaseContracts.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

import {IDUSXProvider} from "./IDUSXProvider.sol";
import {IERC20Token} from "./IERC20Token.sol";
import {IERC20TokenRebase} from "./IERC20TokenRebase.sol";
import {IFeesDistributor} from "./IFees.sol";
import {IFeesWithdrawer} from "./IFees.sol";
import {IFloor} from "./IFloor.sol";
import {ILenderOwner} from "./ILenderOwner.sol";
import {ILiquidationHelper} from "./ILiquidationHelper.sol";
import {IMarketLens} from "./IMarketLens.sol";
import {IMiscHelper} from "./IMiscHelper.sol";
import {IOracle} from "./IOracle.sol";
import {IPSM} from "./IPSM.sol";
import {IRepayHelper} from "./IRepayHelper.sol";
import {IStableOwner} from "./IStableOwner.sol";
import {IStakedDUSX} from "./IStakedDUSX.sol";
import {ISupplyHangingCalculator} from "./ISupplyHangingCalculator.sol";
import {IVault} from "./IVault.sol";
import {IVoteEscrowedSTTX} from "./IVoteEscrowedSTTX.sol";
import {IDynamicInterestRate} from "./IDynamicInterestRate.sol";
import {IMinter} from "./IMinter.sol";

interface IBaseContracts {
    struct CoreTokens {
        IERC20Token dusx;
        IERC20TokenRebase sttx;
        IStakedDUSX stDUSX;
        IVoteEscrowedSTTX veSTTX;
    }
    struct PSMContracts {
        IPSM psmCircle;
        IPSM psmTether;
        IStableOwner stableOwner;
    }
    struct OracleContracts {
        IOracle oracleChainlink;
        IOracle oracleFloorPrice;
    }
    struct HelperContracts {
        IMiscHelper helper;
        ILiquidationHelper liquidationHelper;
        IRepayHelper repayHelper;
        IMarketLens marketLens;
    }
    error ZeroAddress();
    error ContractAlreadySet();

    // Struct getters
    function coreTokens() external view returns (CoreTokens memory);

    function psmContracts() external view returns (PSMContracts memory);

    function oracleContracts() external view returns (OracleContracts memory);

    function helperContracts() external view returns (HelperContracts memory);

    // Individual contract getters
    function dusxProvider() external view returns (IDUSXProvider);

    function feesDistributor() external view returns (IFeesDistributor);

    function feesWithdrawer() external view returns (IFeesWithdrawer);

    function floor() external view returns (IFloor);

    function lenderOwner() external view returns (ILenderOwner);

    function minter() external view returns (IMinter);

    function supplyCalculator()
        external
        view
        returns (ISupplyHangingCalculator);

    function vault() external view returns (IVault);

    function dynamicInterestRate() external view returns (IDynamicInterestRate);

    // Convenience getters for struct members
    function dusx() external view returns (IERC20Token);

    function sttx() external view returns (IERC20TokenRebase);

    function stDUSX() external view returns (IStakedDUSX);

    function veSTTX() external view returns (IVoteEscrowedSTTX);

    function psmCircle() external view returns (IPSM);

    function psmTether() external view returns (IPSM);

    function stableOwner() external view returns (IStableOwner);

    function oracleChainlink() external view returns (IOracle);

    function oracleFloorPrice() external view returns (IOracle);

    function helper() external view returns (IMiscHelper);

    function liquidationHelper() external view returns (ILiquidationHelper);

    function repayHelper() external view returns (IRepayHelper);

    function marketLens() external view returns (IMarketLens);
}

File 12 of 33 : IDUSXProvider.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

/**
 * @title IDUSXProvider
 * @dev Interface for DUSX token provision and distribution operations
 * @notice Defines functionality for:
 * 1. Token provision management
 * 2. Supply control
 * 3. Distribution tracking
 */
interface IDUSXProvider {
    /*//////////////////////////////////////////////////////////////
                        PROVISION OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Provides DUSX tokens to the requesting address
     * @param amount The quantity of DUSX tokens to provide in base units
     * @dev Handles:
     * · Token minting/transfer
     * · Supply tracking
     * · State updates
     *
     * Requirements:
     * · Caller is authorized
     * · Amount > 0
     * · Within supply limits
     *
     * Effects:
     * · Increases recipient balance
     * · Updates total supply
     * · Emits provision event
     */
    function provide(uint256 amount) external;
}

File 13 of 33 : IDynamicInterestRate.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

/**
 * @title IDynamicInterestRate
 * @dev Interface for dynamic interest rate calculations in the lending protocol
 * @notice Defines methods for retrieving time-based interest rates that:
 * 1. Adjust based on market conditions
 * 2. Support per-second and base rate calculations
 * 3. Maintain precision through proper scaling
 *
 * This interface is crucial for:
 * · Accurate interest accrual
 * · Dynamic market response
 * · Protocol yield calculations
 */
interface IDynamicInterestRate {
    /*//////////////////////////////////////////////////////////////
                        INTEREST RATE QUERIES
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Retrieves the current interest rate per second
     * @return uint256 Interest rate per second, scaled by 1e18
     * @dev Used for precise interest calculations over time periods
     */
    function getInterestPerSecond() external view returns (uint256);

    /**
     * @notice Retrieves the current base interest rate
     * @return uint256 Base interest rate, scaled by 1e18
     * @dev Represents the foundational rate before adjustments
     */
    function getInterestRate() external view returns (uint256);
}

File 14 of 33 : IERC20Custom.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

/**
 * @title IERC20Custom
 * @dev Interface for the ERC20 fungible token standard (EIP-20)
 * @notice Defines functionality for:
 * 1. Token transfers
 * 2. Allowance management
 * 3. Balance tracking
 * 4. Token metadata
 */
interface IERC20Custom {
    /*//////////////////////////////////////////////////////////////
                                EVENTS
    //////////////////////////////////////////////////////////////*/
    /**
     * @dev Emitted on token transfer between addresses
     * @param from Source address (0x0 for mints)
     * @param to Destination address (0x0 for burns)
     * @param value Amount of tokens transferred
     * @notice Tracks:
     * · Regular transfers
     * · Minting operations
     * · Burning operations
     */
    event Transfer(address indexed from, address indexed to, uint256 value);
    /**
     * @dev Emitted when spending allowance is granted
     * @param owner Address granting permission
     * @param spender Address receiving permission
     * @param value Amount of tokens approved
     * @notice Records:
     * · New approvals
     * · Updated allowances
     * · Revoked permissions
     */
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );

    /*//////////////////////////////////////////////////////////////
                        TRANSFER OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Transfers tokens to specified recipient
     * @param to Recipient address
     * @param value Amount to transfer in base units
     * @return bool True if transfer succeeds
     * @dev Requirements:
     * · Caller has sufficient balance
     * · Recipient is valid
     * · Amount > 0
     *
     * Effects:
     * · Decreases caller balance
     * · Increases recipient balance
     * · Emits Transfer event
     */
    function transfer(address to, uint256 value) external returns (bool);

    /**
     * @notice Executes transfer on behalf of token owner
     * @param from Source address
     * @param to Destination address
     * @param value Amount to transfer in base units
     * @return bool True if transfer succeeds
     * @dev Requirements:
     * · Caller has sufficient allowance
     * · Source has sufficient balance
     * · Valid addresses
     *
     * Effects:
     * · Decreases allowance
     * · Updates balances
     * · Emits Transfer event
     */
    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);

    /*//////////////////////////////////////////////////////////////
                        APPROVAL OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Authorizes address to spend tokens
     * @param spender Address to authorize
     * @param value Amount to authorize in base units
     * @return bool True if approval succeeds
     * @dev Controls:
     * · Spending permissions
     * · Delegation limits
     * · Authorization levels
     *
     * Security:
     * · Overwrites previous allowance
     * · Requires explicit value
     * · Emits Approval event
     */
    function approve(address spender, uint256 value) external returns (bool);

    /*//////////////////////////////////////////////////////////////
                            TOKEN METADATA
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Retrieves human-readable token name
     * @return string Full token name
     */
    function name() external view returns (string memory);

    /**
     * @notice Retrieves token trading symbol
     * @return string Short token identifier
     */
    function symbol() external view returns (string memory);

    /**
     * @notice Retrieves token decimal precision
     * @return uint8 Number of decimal places
     * @dev Standard:
     * · 18 for most tokens
     * · Used for display formatting
     */
    function decimals() external view returns (uint8);

    /*//////////////////////////////////////////////////////////////
                            BALANCE QUERIES
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Retrieves total token supply
     * @return uint256 Current total supply
     * @dev Reflects:
     * · All minted tokens
     * · Minus burned tokens
     * · In base units
     */
    function totalSupply() external view returns (uint256);

    /**
     * @notice Retrieves account token balance
     * @param account Address to query
     * @return uint256 Current balance in base units
     * @dev Returns:
     * · Available balance
     * · Includes pending rewards
     * · Excludes locked tokens
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @notice Retrieves remaining spending allowance
     * @param owner Token owner address
     * @param spender Authorized spender address
     * @return uint256 Current allowance in base units
     * @dev Shows:
     * · Approved amount
     * · Remaining limit
     * · Delegation status
     */
    function allowance(
        address owner,
        address spender
    ) external view returns (uint256);
}

File 15 of 33 : IERC20Token.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

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

/**
 * @title IERC20Token
 * @dev Extended interface for ERC20 tokens with supply control capabilities
 * @notice Defines functionality for:
 * 1. Token minting
 * 2. Token burning
 * 3. Supply management
 */
interface IERC20Token is IERC20Custom {
    /*//////////////////////////////////////////////////////////////
                        SUPPLY MANAGEMENT
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Mints new tokens to specified account
     * @param account Address to receive minted tokens
     * @param amount Quantity of tokens to mint in base units
     * @dev Controls:
     * · Supply expansion
     * · Balance updates
     * · Event emission
     *
     * Requirements:
     * · Caller is authorized
     * · Within maxSupply
     * · Valid recipient
     */
    function mint(address account, uint256 amount) external;

    /**
     * @notice Burns tokens from specified account
     * @param account Address to burn tokens from
     * @param amount Quantity of tokens to burn in base units
     * @dev Manages:
     * · Supply reduction
     * · Balance updates
     * · Event emission
     *
     * Requirements:
     * · Caller is authorized
     * · Sufficient balance
     * · Amount > 0
     */
    function burn(address account, uint256 amount) external;

    /*//////////////////////////////////////////////////////////////
                            VIEW FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Retrieves maximum token supply limit
     * @return uint256 Maximum supply cap in base units
     * @dev Enforces:
     * · Supply ceiling
     * · Mint restrictions
     * · Protocol limits
     *
     * Note: This is an immutable value that
     * cannot be exceeded by minting operations
     */
    function maxSupply() external view returns (uint256);
}

File 16 of 33 : IERC20TokenRebase.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

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

/**
 * @title IERC20TokenRebase
 * @dev Extended interface for ERC20 tokens with elastic supply and safe management
 * @notice Defines functionality for:
 * 1. Supply elasticity (rebasing)
 * 2. Safe-based token management
 * 3. Supply control mechanisms
 * 4. Configuration management
 */
interface IERC20TokenRebase is IERC20Custom {
    /*//////////////////////////////////////////////////////////////
                        SUPPLY MANAGEMENT
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Mints new tokens to specified account
     * @param account Address to receive minted tokens
     * @param amount Quantity of tokens to mint in base units
     * @dev Requires:
     * · Caller is authorized minter
     * · Within maxSupply limits
     * · Valid recipient
     */
    function mint(address account, uint256 amount) external;

    /**
     * @notice Burns tokens from specified account
     * @param account Address to burn tokens from
     * @param amount Quantity of tokens to burn in base units
     * @dev Requires:
     * · Caller is authorized
     * · Account has sufficient balance
     * · Amount > 0
     */
    function burn(address account, uint256 amount) external;

    /*//////////////////////////////////////////////////////////////
                        REBASE OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Executes supply rebase based on current parameters
     * @dev Triggers:
     * · Supply adjustment
     * · Balance recalculation
     * · Event emission
     *
     * Considers:
     * · Rebase interval
     * · Basis points
     * · Supply limits
     */
    function rebase() external;

    /**
     * @notice Configures rebase parameters
     * @param rebaseInterval Time period between rebases (in seconds)
     * @param rebaseBasisPoints Scale factor for rebase (in basis points)
     * @dev Controls:
     * · Rebase frequency
     * · Rebase magnitude
     * · Supply elasticity
     */
    function setRebaseConfig(
        uint256 rebaseInterval,
        uint256 rebaseBasisPoints
    ) external;

    /*//////////////////////////////////////////////////////////////
                        SAFE MANAGEMENT
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Initializes new token management safe
     * @param safe Address of safe to create
     * @dev Establishes:
     * · Safe permissions
     * · Access controls
     * · Management capabilities
     */
    function createSafe(address safe) external;

    /**
     * @notice Removes existing token management safe
     * @param safe Address of safe to remove
     * @dev Handles:
     * · Permission revocation
     * · State cleanup
     * · Access termination
     */
    function destroySafe(address safe) external;

    /*//////////////////////////////////////////////////////////////
                            VIEW FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Retrieves floor contract address
     * @return address Active floor contract
     * @dev Used for:
     * · Price stability
     * · Supply control
     */
    function floor() external view returns (address);

    /**
     * @notice Retrieves authorized minter address
     * @return address Active minter contract
     * @dev Controls:
     * · Mint permissions
     * · Supply expansion
     */
    function minter() external view returns (address);

    /**
     * @notice Returns absolute maximum token supply
     * @return uint256 Maximum supply cap in base units
     * @dev Enforces:
     * · Hard supply limit
     * · Mint restrictions
     */
    function maxSupply() external view returns (uint256);

    /**
     * @notice Calculates maximum supply after rebase
     * @return uint256 Post-rebase maximum supply in base units
     * @dev Considers:
     * · Current max supply
     * · Rebase parameters
     * · Supply caps
     */
    function maxSupplyRebased() external view returns (uint256);

    /**
     * @notice Calculates total supply after rebase
     * @return uint256 Post-rebase total supply in base units
     * @dev Reflects:
     * · Current supply
     * · Rebase effects
     * · Supply limits
     */
    function totalSupplyRebased() external view returns (uint256);
}

File 17 of 33 : IFees.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

/**
 * @title IFeesWithdrawer
 * @dev Interface for protocol fee withdrawal operations
 * @notice Defines functionality for:
 * 1. Secure fee withdrawal
 * 2. Access control for withdrawals
 * 3. Protocol revenue management
 *
 * This interface ensures:
 * · Controlled access to protocol fees
 * · Safe transfer of accumulated revenue
 * · Proper accounting of withdrawn amounts
 */
interface IFeesWithdrawer {
    /*//////////////////////////////////////////////////////////////
                        WITHDRAWAL OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Withdraws accumulated protocol fees to designated recipients
     * @dev Only callable by authorized withdrawers
     * Handles:
     * · Fee accounting updates
     * · Transfer of tokens
     * · Event emission for tracking
     */
    function withdraw() external;
}

/**
 * @title IFeesDistributor
 * @dev Interface for protocol fee distribution and allocation
 * @notice Defines functionality for:
 * 1. Fee distribution across protocol components
 * 2. Dynamic allocation management
 * 3. Floor token revenue sharing
 *
 * This interface manages:
 * · Revenue distribution logic
 * · Allocation percentages
 * · Protocol incentive mechanisms
 */
interface IFeesDistributor {
    /*//////////////////////////////////////////////////////////////
                        DISTRIBUTION OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Distributes accumulated protocol fees according to set allocations
     * @dev Handles the distribution of fees to:
     * · Floor token stakers
     * · Protocol treasury
     * · Other designated recipients
     */
    function distribute() external;

    /*//////////////////////////////////////////////////////////////
                            VIEW FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Returns current percentage allocated to Floor token stakers
     * @return uint256 Floor allocation percentage, scaled by 1e18
     */
    function floorAllocation() external view returns (uint256);
}

File 18 of 33 : IFloor.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

/**
 * @title IFloor
 * @dev Interface for protocol floor price management and capital operations
 * @notice Defines functionality for:
 * 1. Token deposit management
 * 2. Refund processing
 * 3. Capital tracking
 */
interface IFloor {
    /*//////////////////////////////////////////////////////////////
                        DEPOSIT OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Processes token deposits into the floor contract
     * @param msgSender Address initiating the deposit
     * @param amount Quantity of tokens to deposit
     * @dev Handles:
     * · Token transfer validation
     * · Capital tracking updates
     * · Event emission
     */
    function deposit(address msgSender, uint256 amount) external;

    /*//////////////////////////////////////////////////////////////
                        REFUND OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Processes token refunds from the floor contract
     * @param msgSender Address receiving the refund
     * @param amount Quantity of tokens to refund
     * @dev Ensures:
     * · Sufficient contract balance
     * · Authorized withdrawal
     * · Capital accounting
     */
    function refund(address msgSender, uint256 amount) external;

    /*//////////////////////////////////////////////////////////////
                            VIEW FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Returns current total capital held in the floor contract
     * @return uint256 Current capital amount in base units
     * @dev Used for:
     * · Floor price calculations
     * · Protocol health metrics
     * · Capital adequacy checks
     */
    function capital() external view returns (uint256);
}

File 19 of 33 : ILender.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

import {Rebase} from "../library/AuxRebase.sol";
import {IERC20Custom} from "./IERC20Custom.sol";
import {IOracle} from "./IOracle.sol";
import {IVault} from "./IVault.sol";

/**
 * @title ILender
 * @dev Interface for lending operations and management
 * @notice Defines the core lending protocol functionality including:
 * 1. Collateral management and borrowing operations
 * 2. Interest rate and fee management
 * 3. Liquidation handling
 * 4. Vault integration
 *
 * The interface is designed to support:
 * · Over-collateralized lending
 * · Dynamic interest rates
 * · Liquidation mechanisms
 * · Fee collection and distribution
 */
interface ILender {
    /*//////////////////////////////////////////////////////////////
                        ADMIN CONFIGURATION
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Updates the interest rate for borrowing
     * @param newInterestRate New interest rate (scaled by 1e18)
     */
    function changeInterestRate(uint256 newInterestRate) external;

    /**
     * @notice Sets global and per-address borrowing limits
     * @param newBorrowLimit Total borrowing limit for the protocol
     * @param perAddressPart Maximum borrow amount per address
     */
    function changeBorrowLimit(
        uint256 newBorrowLimit,
        uint256 perAddressPart
    ) external;

    /*//////////////////////////////////////////////////////////////
                        CORE LENDING OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Updates protocol state with accrued interest
     */
    function accrue() external;

    /**
     * @notice Updates the exchange rate from the oracle
     */
    function updateExchangeRate() external;

    /**
     * @notice Withdraws accumulated protocol fees
     * @param amountToProvide Amount of fees to withdraw
     */
    function withdrawFees(uint256 amountToProvide) external;

    /*//////////////////////////////////////////////////////////////
                        LIQUIDATION HANDLING
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Liquidates undercollateralized positions
     * @param liquidator Address performing the liquidation
     * @param users Array of user addresses to liquidate
     * @param maxBorrowParts Maximum borrow parts to liquidate per user
     * @param to Address to receive liquidated collateral
     */
    function liquidate(
        address liquidator,
        address[] memory users,
        uint256[] memory maxBorrowParts,
        address to
    ) external;

    /*//////////////////////////////////////////////////////////////
                        VAULT OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Deposits collateral into the vault
     * @param amount Amount of collateral to deposit
     */
    function vaultDepositAddCollateral(uint256 amount) external;

    /**
     * @notice Withdraws borrowed assets from the vault
     * @param msgSender Address initiating the withdrawal
     * @param amount Amount to withdraw
     * @return part Borrow part assigned
     * @return share Share of the vault
     */
    function borrowVaultWithdraw(
        address msgSender,
        uint256 amount
    ) external returns (uint256 part, uint256 share);

    /*//////////////////////////////////////////////////////////////
                        COLLATERAL MANAGEMENT
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Adds collateral to a lending position
     * @param to Address to credit the collateral
     * @param skim True to skim tokens from the contract
     * @param share Amount of shares to add as collateral
     */
    function addCollateral(address to, bool skim, uint256 share) external;

    /**
     * @notice Removes collateral from a lending position
     * @param to Address to receive the removed collateral
     * @param share Amount of shares to remove
     */
    function removeCollateral(address to, uint256 share) external;

    /*//////////////////////////////////////////////////////////////
                        BORROWING OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Borrows assets against deposited collateral
     * @param msgSender Address initiating the borrow
     * @param amount Amount to borrow
     * @return part Borrow part assigned
     * @return share Share of the borrowed amount
     */
    function borrow(
        address msgSender,
        uint256 amount
    ) external returns (uint256 part, uint256 share);

    /**
     * @notice Repays borrowed assets
     * @param payer Address paying the debt
     * @param to Address whose debt to repay
     * @param skim True to skim tokens from the contract
     * @param part Amount of borrow part to repay
     * @return amount Actual amount repaid
     */
    function repay(
        address payer,
        address to,
        bool skim,
        uint256 part
    ) external returns (uint256 amount);

    /*//////////////////////////////////////////////////////////////
                            VIEW FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Gets the oracle contract address
     * @return IOracle Oracle interface
     */
    function oracle() external view returns (IOracle);

    /**
     * @notice Gets interest accrual information
     * @return Last accrual timestamp, accumulated interest, interest per second
     */
    function accrueInfo() external view returns (uint256, uint256, uint256);

    /**
     * @notice Gets the required collateral ratio
     * @return uint256 Collateral ratio (scaled by 1e5)
     */
    function collateralRatio() external view returns (uint256);

    /**
     * @notice Gets the liquidation bonus multiplier
     * @return uint256 Liquidation multiplier (scaled by 1e5)
     */
    function liquidationMultiplier() external view returns (uint256);

    /**
     * @notice Gets total collateral shares in the protocol
     * @return uint256 Total collateral share amount
     */
    function totalCollateralShare() external view returns (uint256);

    /**
     * @notice Gets the vault contract address
     * @return IVault Vault interface
     */
    function vault() external view returns (IVault);

    /**
     * @notice Gets the fee recipient address
     * @return address Fee recipient
     */
    function feeTo() external view returns (address);

    /**
     * @notice Gets the collateral token address
     * @return IERC20Custom Collateral token interface
     */
    function collateral() external view returns (IERC20Custom);

    /**
     * @notice Gets total borrow state
     * @return Rebase Total borrow information
     */
    function totalBorrow() external view returns (Rebase memory);

    /**
     * @notice Gets user's borrow part
     * @param account User address
     * @return uint256 User's borrow part
     */
    function userBorrowPart(address account) external view returns (uint256);

    /**
     * @notice Gets user's collateral share
     * @param account User address
     * @return uint256 User's collateral share
     */
    function userCollateralShare(
        address account
    ) external view returns (uint256);

    /**
     * @notice Gets protocol borrowing limits
     * @return total Total protocol borrow limit
     * @return borrowPartPerAddress Per-address borrow limit
     */
    function borrowLimit()
        external
        view
        returns (uint256 total, uint256 borrowPartPerAddress);

    /**
     * @notice Gets the DUSX token address
     * @return IERC20Custom DUSX token interface
     */
    function dusx() external view returns (IERC20Custom);

    /**
     * @notice Gets all accounts with active positions
     * @return address[] Array of account addresses
     */
    function accounts() external view returns (address[] memory);

    /**
     * @notice Gets the collateral precision factor
     * @return uint256 Collateral precision
     */
    function collateralPrecision() external view returns (uint256);
}

File 20 of 33 : ILenderOwner.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

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

/**
 * @title ILenderOwner
 * @dev Interface for protocol-level lender management and configuration
 * @notice Defines functionality for:
 * 1. Interest rate management
 * 2. Borrow limit control
 * 3. Risk parameter adjustment
 */
interface ILenderOwner {
    /*//////////////////////////////////////////////////////////////
                        INTEREST MANAGEMENT
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Updates lender's interest rate configuration
     * @param lender The lender contract to modify
     * @param newInterestRate New interest rate value in basis points
     * @dev Controls:
     * · Interest accrual
     * · Yield generation
     * · Protocol revenue
     *
     * Requirements:
     * · Caller is authorized
     * · Rate within bounds
     * · Valid lender contract
     */
    function changeInterestRate(
        ILender lender,
        uint256 newInterestRate
    ) external;

    /*//////////////////////////////////////////////////////////////
                        LIMIT MANAGEMENT
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Updates lender's borrowing constraints
     * @param lender The lender contract to modify
     * @param newBorrowLimit New total protocol borrow limit
     * @param perAddressPart Maximum borrow limit per address
     * @dev Manages:
     * · Protocol exposure
     * · Individual limits
     * · Risk thresholds
     *
     * Requirements:
     * · Caller is authorized
     * · Valid limits
     * · perAddressPart <= newBorrowLimit
     *
     * Security:
     * · Prevents overleveraging
     * · Controls risk exposure
     * · Ensures protocol stability
     */
    function changeBorrowLimit(
        ILender lender,
        uint256 newBorrowLimit,
        uint256 perAddressPart
    ) external;

    /*//////////////////////////////////////////////////////////////
                        DEPRECATION MANAGEMENT
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Checks if a lender contract is deprecated
     * @param lender The lender address to check
     * @return bool True if the lender is deprecated, false otherwise
     * @dev Used to:
     * · Prevent operations on deprecated markets
     * · Control market lifecycle
     * · Manage protocol upgrades
     *
     * Security:
     * · Read-only function
     * · No state modifications
     * · Access control not required
     */
    function deprecated(address lender) external view returns (bool);

    /**
     * @notice Checks if a lender contract is in manual mode
     * @param lender The lender address to check
     * @return bool True if the lender is in manual mode, false otherwise
     * @dev Used to:
     * · Determine if borrow limits are managed manually
     * · Control automatic interest rate adjustments
     *
     * Security:
     * · Read-only function
     * · No state modifications
     * · Access control not required
     */
    function manual(address lender) external view returns (bool);
}

File 21 of 33 : ILiquidationHelper.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

import {IERC20Custom} from "./IERC20Custom.sol";
import {ILender} from "../interface/ILender.sol";
import {IMiscHelper} from "../interface/IMiscHelper.sol";

/**
 * @title ILiquidationHelper
 * @dev Interface for liquidation assistance operations
 * @notice Defines comprehensive liquidation functionality including:
 * 1. Direct liquidation execution
 * 2. Liquidation amount calculations
 * 3. Position health checks
 * 4. Preview and simulation functions
 *
 * The helper provides:
 * · Maximum and partial liquidation support
 * · Customizable recipient addresses
 * · Pre-execution liquidation simulations
 * · Automated DUSX amount calculations
 */
interface ILiquidationHelper {
    /*//////////////////////////////////////////////////////////////
                            CONFIGURATION
    //////////////////////////////////////////////////////////////*/
    /*//////////////////////////////////////////////////////////////
                        LIQUIDATION EXECUTION
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Liquidates maximum possible amount for an account
     * @param lender Address of the lending contract
     * @param account Address to be liquidated
     * @return collateralAmount Amount of collateral received
     * @return adjustedBorrowPart Adjusted borrow amount after liquidation
     * @return requiredDUSXAmount DUSX tokens needed to execute liquidation
     * @dev Automatically calculates maximum liquidatable amount
     */
    function liquidateMax(
        ILender lender,
        address account
    )
        external
        returns (
            uint256 collateralAmount,
            uint256 adjustedBorrowPart,
            uint256 requiredDUSXAmount
        );

    /**
     * @notice Liquidates specific amount for an account
     * @param lender Address of the lending contract
     * @param account Address to be liquidated
     * @param borrowPart Amount of borrow position to liquidate
     * @return collateralAmount Amount of collateral received
     * @return adjustedBorrowPart Adjusted borrow amount after liquidation
     * @return requiredDUSXAmount DUSX tokens needed to execute liquidation
     * @dev Validates borrowPart against maximum liquidatable amount
     */
    function liquidate(
        ILender lender,
        address account,
        uint256 borrowPart
    )
        external
        returns (
            uint256 collateralAmount,
            uint256 adjustedBorrowPart,
            uint256 requiredDUSXAmount
        );

    /*//////////////////////////////////////////////////////////////
                    LIQUIDATION WITH CUSTOM RECIPIENT
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Liquidates maximum amount and sends to specified recipient
     * @param lender Address of the lending contract
     * @param account Address to be liquidated
     * @param recipient Address to receive liquidated assets
     * @dev Combines max liquidation with custom recipient
     */
    function liquidateMaxTo(
        ILender lender,
        address account,
        address recipient
    ) external;

    /**
     * @notice Liquidates specific amount and sends to specified recipient
     * @param lender Address of the lending contract
     * @param account Address to be liquidated
     * @param recipient Address to receive liquidated assets
     * @param borrowPart Amount of borrow position to liquidate
     * @dev Combines partial liquidation with custom recipient
     */
    function liquidateTo(
        ILender lender,
        address account,
        address recipient,
        uint256 borrowPart
    ) external;

    /*//////////////////////////////////////////////////////////////
                        LIQUIDATION PREVIEWS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Previews maximum possible liquidation amounts
     * @param lender Address of the lending contract
     * @param account Address to check
     * @return liquidatable Whether the account can be liquidated
     * @return requiredDUSXAmount DUSX tokens needed for liquidation
     * @return adjustedBorrowPart Final borrow amount after liquidation
     * @return returnedCollateralAmount Collateral amount to be received
     * @dev Simulates liquidation without executing
     */
    function previewMaxLiquidation(
        ILender lender,
        address account
    )
        external
        view
        returns (
            bool liquidatable,
            uint256 requiredDUSXAmount,
            uint256 adjustedBorrowPart,
            uint256 returnedCollateralAmount
        );

    /**
     * @notice Previews specific liquidation amounts
     * @param lender Address of the lending contract
     * @param account Address to check
     * @param borrowPart Amount of borrow position to liquidate
     * @return liquidatable Whether the account can be liquidated
     * @return requiredDUSXAmount DUSX tokens needed for liquidation
     * @return adjustedBorrowPart Final borrow amount after liquidation
     * @return returnedCollateralAmount Collateral amount to be received
     * @dev Simulates partial liquidation without executing
     */
    function previewLiquidation(
        ILender lender,
        address account,
        uint256 borrowPart
    )
        external
        view
        returns (
            bool liquidatable,
            uint256 requiredDUSXAmount,
            uint256 adjustedBorrowPart,
            uint256 returnedCollateralAmount
        );

    /*//////////////////////////////////////////////////////////////
                            VIEW FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Checks if an account is eligible for liquidation
     * @param lender Address of the lending contract
     * @param account Address to check
     * @return bool True if account can be liquidated
     * @dev Considers collateral ratio and position health
     */
    function isLiquidatable(
        ILender lender,
        address account
    ) external view returns (bool);

    /**
     * @notice Returns the DUSX token contract used for liquidations
     * @return IERC20Custom DUSX token interface
     * @dev DUSX is required to execute liquidations
     */
    function dusx() external view returns (IERC20Custom);

    /**
     * @notice Returns the helper utility contract
     * @return IMiscHelper Helper interface for additional functions
     * @dev Helper provides supporting calculations and checks
     */
    function helper() external view returns (IMiscHelper);
}

File 22 of 33 : IMarketLens.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

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

/**
 * @title IMarketLens
 * @dev Interface for viewing and analyzing lending market data
 * @notice Provides functionality for:
 * 1. Market size analysis
 * 2. Borrowing metrics
 * 3. Risk assessment data
 */
interface IMarketLens {
    /*//////////////////////////////////////////////////////////////
                            MARKET METRICS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Calculates total borrowed amount from a specific lending market
     * @param lender Address of the lending market to analyze
     * @return uint256 Total borrowed amount in base units
     * @dev Aggregates:
     * · Active loan positions
     * · Accrued interest
     * · Pending liquidations
     *
     * Used for:
     * · Market size analysis
     * · Risk assessment
     * · Protocol health monitoring
     */
    function getTotalBorrowed(ILender lender) external view returns (uint256);
}

File 23 of 33 : IMinter.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

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

/**
 * @title IMinter
 * @dev Interface for the Minter contract
 */
interface IMinter {
    /**
     * @notice Enables whitelist minting phase
     */
    function enableWhitelistMint() external;

    /**
     * @notice Enables public minting phase
     */
    function enablePublicMint() external;

    /**
     * @notice Adds a wallet to the whitelist
     * @param wallet Wallet address to whitelist
     */
    function addToWhitelist(address wallet) external;

    /**
     * @notice Mints tokens during whitelist phase
     * @param stablecoin Stablecoin used for minting
     * @param stableAmount Amount of stablecoin to mint against
     */
    function whitelistMint(
        IERC20Custom stablecoin,
        uint256 stableAmount
    ) external;

    /**
     * @notice Mints tokens during public phase
     * @param stablecoin Stablecoin used for minting
     * @param stableAmount Amount of stablecoin to mint against
     */
    function publicMint(IERC20Custom stablecoin, uint256 stableAmount) external;

    /**
     * @notice Mints remaining token supply
     * @param stablecoin Stablecoin used for minting
     */
    function mintRemainingSupply(IERC20Custom stablecoin) external;

    /**
     * @notice Sends accumulated DUSX to floor contract
     */
    function sendToFloorDUSX() external;

    /**
     * @notice Verifies if a wallet is whitelisted
     * @param wallet Address to verify
     * @return bool Whitelist status
     */
    function verifyWallet(address wallet) external view returns (bool);

    /**
     * @notice Calculates mint amount for given stablecoin input
     * @param stablecoin Stablecoin used for calculation
     * @param stableAmount Amount of stablecoin
     * @return uint256 Calculated mint amount
     */
    function calcMintAmount(
        IERC20Custom stablecoin,
        uint256 stableAmount
    ) external view returns (uint256);

    /**
     * @notice Gets the current token reserve
     * @return uint256 Current token reserve
     */
    function tokenReserve() external view returns (uint256);

    /**
     * @notice Gets the current mint ratio
     * @return uint256 Current mint ratio
     */
    function getCurrentRatio() external view returns (uint256);

    /**
     * @notice Gets the current mint rate
     * @return uint256 Current mint rate
     */
    function getCurrentRate() external view returns (uint256);
}

File 24 of 33 : IMiscHelper.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

import {IDynamicInterestRate} from "./IDynamicInterestRate.sol";
import {IFeesDistributor} from "./IFees.sol";
import {IFeesWithdrawer} from "./IFees.sol";
import {IFloor} from "./IFloor.sol";
import {ILender} from "./ILender.sol";
import {ILenderOwner} from "./ILenderOwner.sol";
import {ILiquidationHelper} from "./ILiquidationHelper.sol";
import {IMarketLens} from "./IMarketLens.sol";
import {IPSM} from "./IPSM.sol";
import {IRepayHelper} from "./IRepayHelper.sol";
import {IStakedDUSX} from "./IStakedDUSX.sol";
import {ISupplyHangingCalculator} from "./ISupplyHangingCalculator.sol";

/**
 * @title IMiscHelper
 * @dev Interface for miscellaneous helper functions across the protocol
 * @notice Provides comprehensive helper methods for:
 * 1. Protocol configuration and parameter management
 * 2. Floor token operations
 * 3. Staked DUSX token management
 * 4. PSM (Peg Stability Module) operations
 * 5. Lending operations including borrowing and repayment
 * 6. System-wide view functions
 *
 * This interface acts as a central utility hub for coordinating
 * various protocol components and simplifying complex operations
 */
interface IMiscHelper {
    /*//////////////////////////////////////////////////////////////
                        CONFIGURATION FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Sets the supply hanging calculator contract
     * @param supplyHangingCalculator_ New calculator contract address
     * @dev Used for calculating supply adjustments
     */
    function setSupplyHangingCalculator(
        ISupplyHangingCalculator supplyHangingCalculator_
    ) external;

    /**
     * @notice Sets core protocol parameters and contract addresses
     * @param repayHelper_ Repayment helper contract
     * @param liquidationHelper_ Liquidation helper contract
     * @param dynamicInterestRate_ Interest rate calculator
     * @param feesDistributor_ Fee distribution contract
     * @param feesWithdrawer_ Fee withdrawal contract
     * @param lenderOwner_ Lender owner contract
     * @param marketLens_ Market data viewer contract
     * @dev Updates all main protocol component addresses
     */
    function setParameters(
        IRepayHelper repayHelper_,
        ILiquidationHelper liquidationHelper_,
        IDynamicInterestRate dynamicInterestRate_,
        IFeesDistributor feesDistributor_,
        IFeesWithdrawer feesWithdrawer_,
        ILenderOwner lenderOwner_,
        IMarketLens marketLens_
    ) external;

    /**
     * @notice Sets the list of active lender contracts
     * @param lenders_ Array of lender addresses
     * @dev Updates the protocol's lending markets
     */
    function setLenders(ILender[] memory lenders_) external;

    /**
     * @notice Sets the list of PSM contracts
     * @param pegStabilityModules_ Array of PSM addresses
     * @dev Updates available stablecoin PSM modules
     */
    function setPegStabilityModules(
        IPSM[] memory pegStabilityModules_
    ) external;

    /*//////////////////////////////////////////////////////////////
                        FLOOR TOKEN OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Deposits Floor tokens into the protocol
     * @param amount Amount of Floor tokens to deposit
     */
    function depositFloor(uint256 amount) external;

    /**
     * @notice Refunds Floor tokens from the protocol
     * @param amount Amount of Floor tokens to refund
     */
    function refundFloor(uint256 amount) external;

    /*//////////////////////////////////////////////////////////////
                        STAKED DUSX OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Deposits DUSX tokens for staking
     * @param amount Amount of DUSX to stake
     */
    function depositStakedDUSX(uint256 amount) external;

    /**
     * @notice Withdraws staked DUSX tokens
     * @param amount Amount of staked DUSX to withdraw
     */
    function withdrawStakedDUSX(uint256 amount) external;

    /*//////////////////////////////////////////////////////////////
                            PSM OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Swaps DUSX for stablecoin through PSM
     * @param psm PSM contract to use for swap
     * @param receiver Address to receive stablecoins
     * @param amountDUSX Amount of DUSX to swap
     */
    function psmSwapDUSXForStable(
        IPSM psm,
        address receiver,
        uint256 amountDUSX
    ) external;

    /**
     * @notice Swaps stablecoin for DUSX through PSM
     * @param psm PSM contract to use for swap
     * @param receiver Address to receive DUSX
     * @param amountStable Amount of stablecoin to swap
     */
    function psmSwapStableForDUSX(
        IPSM psm,
        address receiver,
        uint256 amountStable
    ) external;

    /*//////////////////////////////////////////////////////////////
                        LENDING OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Withdraws borrowed tokens from vault
     * @param lender Lender contract to withdraw from
     * @param amount Amount to withdraw
     */
    function lenderBorrowVaultWithdraw(ILender lender, uint256 amount) external;

    /**
     * @notice Executes a borrow operation
     * @param lender Lender contract to borrow from
     * @param amount Amount to borrow
     */
    function lenderBorrow(ILender lender, uint256 amount) external;

    /**
     * @notice Repays borrowed tokens
     * @param lender Lender contract to repay to
     * @param payer Address paying the debt
     * @param to Address receiving any excess
     * @param skim Whether to skim tokens from contract
     * @param part Amount of borrow part to repay
     */
    function lenderRepay(
        ILender lender,
        address payer,
        address to,
        bool skim,
        uint256 part
    ) external;

    /**
     * @notice Executes liquidation for multiple users
     * @param lender Lender contract to liquidate from
     * @param liquidator Address performing liquidation
     * @param users Array of addresses to liquidate
     * @param maxBorrowParts Maximum borrow parts to liquidate per user
     * @param to Address to receive liquidated assets
     */
    function lenderLiquidate(
        ILender lender,
        address liquidator,
        address[] memory users,
        uint256[] memory maxBorrowParts,
        address to
    ) external;

    /*//////////////////////////////////////////////////////////////
                            VIEW FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Returns current APR for staked DUSX
     * @return uint256 Annual percentage rate
     */
    function aprStakedDUSX() external view returns (uint256);

    /**
     * @notice Returns repayment helper contract
     */
    function repayHelper() external view returns (IRepayHelper);

    /**
     * @notice Returns liquidation helper contract
     */
    function liquidationHelper() external view returns (ILiquidationHelper);

    /**
     * @notice Returns dynamic interest rate calculator
     */
    function dynamicInterestRate() external view returns (IDynamicInterestRate);

    /**
     * @notice Returns floor token contract
     */
    function floor() external view returns (IFloor);

    /**
     * @notice Returns fees distributor contract
     */
    function feesDistributor() external view returns (IFeesDistributor);

    /**
     * @notice Returns fees withdrawer contract
     */
    function feesWithdrawer() external view returns (IFeesWithdrawer);

    /**
     * @notice Returns lender contract at specified index
     * @param index Position in lenders array
     */
    function lenders(uint256 index) external view returns (ILender);

    /**
     * @notice Returns total number of lender contracts
     */
    function lendersLength() external view returns (uint256);

    /**
     * @notice Returns lender owner contract
     */
    function lenderOwner() external view returns (ILenderOwner);

    /**
     * @notice Returns market lens contract
     */
    function marketLens() external view returns (IMarketLens);

    /**
     * @notice Returns PSM contract at specified index
     * @param index Position in PSM array
     */
    function pegStabilityModules(uint256 index) external view returns (IPSM);

    /**
     * @notice Returns total number of PSM contracts
     */
    function pegStabilityModulesLength() external view returns (uint256);

    /**
     * @notice Returns staked DUSX token contract
     */
    function stDUSX() external view returns (IStakedDUSX);

    /**
     * @notice Returns supply hanging calculator contract
     */
    function supplyHangingCalculator()
        external
        view
        returns (ISupplyHangingCalculator);
}

File 25 of 33 : IOracle.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

/**
 * @title IOracle
 * @dev Interface for basic price feed operations
 * @notice Defines functionality for:
 * 1. Asset price retrieval
 * 2. Price precision handling
 */
interface IOracle {
    /*//////////////////////////////////////////////////////////////
                            PRICE QUERIES
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Retrieves current asset price
     * @param asset Address of the asset to price
     * @return uint256 Current price in base units with precision
     * @dev Provides:
     * · Latest price data
     * · Standardized precision
     * · Asset valuation
     *
     * Note: Check implementation for specific precision details
     */
    function getPrice(address asset) external view returns (uint256);
}

/**
 * @title ITwapOracle
 * @dev Interface for time-weighted average price calculations
 * @notice Defines functionality for:
 * 1. TWAP updates
 * 2. Time-weighted calculations
 * 3. Price smoothing
 */
interface ITwapOracle {
    /*//////////////////////////////////////////////////////////////
                            TWAP OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Updates time-weighted average price
     * @param asset Address of the asset to update
     * @return uint256 New TWAP value in base units
     * @dev Calculates:
     * · Time-weighted price
     * · Cumulative values
     * · Price averages
     *
     * Features:
     * · Manipulation resistance
     * · Smoothing effect
     * · Historical tracking
     */
    function updateTwap(address asset) external returns (uint256);
}

File 26 of 33 : IPSM.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

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

/**
 * @title IPSM
 * @dev Interface for Peg Stability Module (PSM) operations
 * @notice Defines functionality for:
 * 1. Stablecoin/DUSX swaps
 * 2. Peg maintenance
 * 3. Supply tracking
 */
interface IPSM {
    /*//////////////////////////////////////////////////////////////
                            SWAP OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Executes stablecoin to DUSX swap
     * @param msgSender Address initiating the swap
     * @param receiver Address receiving the DUSX
     * @param stableTokenAmount Amount of stablecoins to swap
     * @dev Handles:
     * · Stablecoin deposit
     * · DUSX minting
     * · Supply tracking
     */
    function swapStableForDUSX(
        address msgSender,
        address receiver,
        uint256 stableTokenAmount
    ) external;

    /**
     * @notice Executes DUSX to stablecoin swap
     * @param msgSender Address initiating the swap
     * @param receiver Address receiving the stablecoins
     * @param stableTokenAmount Amount of stablecoins to receive
     * @dev Handles:
     * · DUSX burning
     * · Stablecoin release
     * · Supply adjustment
     */
    function swapDUSXForStable(
        address msgSender,
        address receiver,
        uint256 stableTokenAmount
    ) external;

    /*//////////////////////////////////////////////////////////////
                            VIEW FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Retrieves the stablecoin token contract
     * @return IERC20Custom Stablecoin token interface
     * @dev Used for:
     * · Token transfers
     * · Balance checks
     * · Allowance verification
     */
    function stableToken() external view returns (IERC20Custom);

    /**
     * @notice Returns total DUSX tokens minted through PSM
     * @return uint256 Total minted amount in base units
     * @dev Tracks:
     * · Total supply impact
     * · PSM utilization
     * · Protocol growth metrics
     */
    function dusxMinted() external view returns (uint256);

    /**
     * @notice Returns the maximum amount of DUSX that can be minted through PSM
     * @return uint256 Maximum mintable amount in base units
     * @dev Used for:
     * · Supply control
     * · Risk management
     * · Protocol safety
     */
    function dusxMintCap() external view returns (uint256);
}

File 27 of 33 : IRepayHelper.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

import {IERC20Custom} from "./IERC20Custom.sol";
import {ILender} from "./ILender.sol";
import {IMiscHelper} from "./IMiscHelper.sol";

/**
 * @title IRepayHelper
 * @dev Interface for streamlined loan repayment operations and management
 * @notice Defines functionality for:
 * 1. Loan repayment processing
 * 2. Multi-loan management
 * 3. Helper contract integration
 * 4. Token interactions
 */
interface IRepayHelper {
    /*//////////////////////////////////////////////////////////////
                        CONFIGURATION
    //////////////////////////////////////////////////////////////*/
    /*//////////////////////////////////////////////////////////////
                        REPAYMENT OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Processes partial loan repayment
     * @param lender Address of the lending contract
     * @param to Address whose loan is being repaid
     * @param amount Amount to repay in base units
     * @return part Share of the loan repaid
     * @dev Handles:
     * · Token transfers
     * · Loan accounting
     * · Share calculations
     *
     * Requirements:
     * · Amount > 0
     * · Sufficient balance
     * · Valid addresses
     */
    function repayAmount(
        ILender lender,
        address to,
        uint256 amount
    ) external returns (uint256 part);

    /**
     * @notice Processes complete loan repayment
     * @param lender Address of the lending contract
     * @param to Address whose loan is being repaid
     * @return amount Total amount repaid in base units
     * @dev Manages:
     * · Full debt calculation
     * · Complete repayment
     * · Account settlement
     *
     * Effects:
     * · Clears entire debt
     * · Updates balances
     * · Emits events
     */
    function repayTotal(
        ILender lender,
        address to
    ) external returns (uint256 amount);

    /**
     * @notice Processes multiple complete loan repayments
     * @param lender Address of the lending contract
     * @param tos Array of addresses whose loans are being repaid
     * @return amount Total amount repaid across all loans
     * @dev Executes:
     * · Batch processing
     * · Multiple settlements
     * · Aggregate accounting
     *
     * Optimizations:
     * · Gas efficient
     * · Bulk processing
     * · Single transaction
     */
    function repayTotalMultiple(
        ILender lender,
        address[] calldata tos
    ) external returns (uint256 amount);

    /*//////////////////////////////////////////////////////////////
                            VIEW FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Retrieves DUSX token contract
     * @return IERC20Custom Interface of the DUSX token
     * @dev Used for:
     * · Token operations
     * · Balance checks
     * · Allowance verification
     */
    function dusx() external view returns (IERC20Custom);

    /**
     * @notice Retrieves helper contract
     * @return IMiscHelper Interface of the helper contract
     * @dev Provides:
     * · Helper functionality
     * · Integration access
     * · Utility methods
     */
    function helper() external view returns (IMiscHelper);
}

File 28 of 33 : IStableOwner.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

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

/**
 * @title IStableOwner Interface
 * @dev Interface for StableOwner contract that manages stable token supply
 * @notice Defines the external interface for stable token supply management
 */
interface IStableOwner {
    /*//////////////////////////////////////////////////////////////
                            EVENTS
    //////////////////////////////////////////////////////////////*/
    /// @notice Emitted when stable token contract is updated
    /// @param stable New stable token contract address
    event StableSet(IERC20Token indexed stable);
    /// @notice Emitted when new tokens are minted
    /// @param account Recipient of minted tokens
    /// @param amount Amount of tokens minted
    event TokensMinted(address indexed account, uint256 amount);
    /// @notice Emitted when tokens are burned
    /// @param account Account tokens were burned from
    /// @param amount Amount of tokens burned
    event TokensBurned(address indexed account, uint256 amount);

    /*//////////////////////////////////////////////////////////////
                            FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /// @notice Updates the stable token contract address
    /// @param stable_ New stable token contract address
    function setStable(IERC20Token stable_) external;

    /// @notice Creates new stable tokens
    /// @param account Address to receive minted tokens
    /// @param amount Number of tokens to mint
    function mint(address account, uint256 amount) external;

    /// @notice Destroys existing stable tokens
    /// @param account Address to burn tokens from
    /// @param amount Number of tokens to burn
    function burn(address account, uint256 amount) external;

    /// @notice The managed stable token contract
    /// @return The IERC20Token interface of the stable token
    function stable() external view returns (IERC20Token);
}

File 29 of 33 : IStakedDUSX.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

/**
 * @title IStakedDUSX
 * @dev Interface for staked DUSX token operations and reward distribution
 * @notice Defines functionality for:
 * 1. DUSX token staking
 * 2. Reward distribution
 * 3. Position management
 */
interface IStakedDUSX {
    /*//////////////////////////////////////////////////////////////
                        REWARD DISTRIBUTION
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Distributes protocol fees as staking rewards
     * @param amount Amount of fees to distribute in base units
     * @dev Handles:
     * · Pro-rata distribution
     * · Reward accounting
     * · Distribution events
     *
     * Rewards are:
     * · Automatically calculated
     * · Immediately available
     * · Proportional to stake
     */
    function distributeFees(uint256 amount) external;

    /**
     * @notice Claims pending fee rewards for the caller
     * @return claimedAmount Amount of fees claimed
     * @dev Allows users to manually claim their accumulated fees
     */
    function claimFees() external returns (uint256 claimedAmount);

    /*//////////////////////////////////////////////////////////////
                        STAKING OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Processes DUSX token deposits for staking
     * @param from Address providing the tokens
     * @param to Address receiving the staked position
     * @param amount Quantity of tokens to stake in base units
     * @dev Manages:
     * · Token transfers
     * · Position creation
     * · Reward calculations
     *
     * Supports:
     * · Direct deposits
     * · Delegated deposits
     * · Position tracking
     */
    function deposit(address from, address to, uint256 amount) external;

    /**
     * @notice Initiates a withdrawal from staked DUSX
     * @param amount Amount of tokens to withdraw
     */
    function beginWithdrawal(uint256 amount) external;

    /**
     * @notice Processes withdrawal of staked DUSX tokens
     * @param account Address withdrawing tokens
     * @dev Handles:
     * · Position updates
     * · Reward claims
     * · Token transfers
     *
     * Ensures:
     * · Sufficient balance
     * · Reward distribution
     * · Clean exit
     */
    function withdraw(address account) external;

    /**
     * @notice Views pending unclaimed fees for an account
     * @param account Address to check for pending fees
     * @return pendingAmount Amount of pending fees available to claim
     * @dev Calculates based on the fee accumulator and account's last claimed value
     */
    function pendingFees(
        address account
    ) external view returns (uint256 pendingAmount);
}

File 30 of 33 : ISupplyHangingCalculator.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

/**
 * @title ISupplyHangingCalculator
 * @dev Interface for calculating and managing token supply adjustments
 * @notice Defines functionality for:
 * 1. Supply hanging calculations
 * 2. Safety margin management
 * 3. Risk-adjusted metrics
 */
interface ISupplyHangingCalculator {
    /*//////////////////////////////////////////////////////////////
                        SAFETY PARAMETERS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Retrieves current safety margin for supply calculations
     * @return uint256 Safety margin percentage scaled by 1e18
     * @dev Used for:
     * · Risk adjustment
     * · Supply buffer
     * · Protocol protection
     */
    function safetyMargin() external view returns (uint256);

    /*//////////////////////////////////////////////////////////////
                    SUPPLY HANGING CALCULATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Calculates current supply hanging with safety margins
     * @return uint256 Risk-adjusted supply hanging in base units
     * @dev Includes:
     * · Safety margin application
     * · Risk adjustments
     * · Protocol constraints
     *
     * Used for:
     * · Safe supply management
     * · Conservative adjustments
     * · Risk-aware operations
     */
    function getSupplyHanging() external view returns (uint256);

    /**
     * @notice Calculates raw supply hanging without safety margins
     * @return uint256 Unadjusted supply hanging in base units
     * @dev Provides:
     * · Raw calculations
     * · No safety buffers
     * · Maximum theoretical values
     *
     * Used for:
     * · Analysis purposes
     * · Maximum bounds
     * · Stress testing
     */
    function getSupplyHangingUnsafe() external view returns (uint256);
}

File 31 of 33 : IVault.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

import {Rebase} from "../library/AuxRebase.sol";
import {IERC20Custom} from "./IERC20Custom.sol";

/**
 * @title IVault
 * @dev Interface for advanced vault operations with elastic share system
 * @notice Defines functionality for:
 * 1. Token custody and management
 * 2. Share-based accounting
 * 3. Elastic supply mechanics
 * 4. Amount/share conversions
 */
interface IVault {
    /*//////////////////////////////////////////////////////////////
                        DEPOSIT OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Processes token deposits into vault
     * @param token Token contract to deposit
     * @param from Source of tokens
     * @param to Recipient of shares
     * @param amount Token amount (in base units, 0 for share-based)
     * @param share Share amount (0 for amount-based)
     * @return amountIn Actual tokens deposited
     * @return shareIn Actual shares minted
     * @dev Handles:
     * · Token transfers
     * · Share minting
     * · Balance updates
     *
     * Requirements:
     * · Valid token contract
     * · Authorized caller
     * · Sufficient balance
     * · Either amount or share > 0
     *
     * Note: Only one of amount/share should be non-zero
     */
    function deposit(
        IERC20Custom token,
        address from,
        address to,
        uint256 amount,
        uint256 share
    ) external returns (uint256 amountIn, uint256 shareIn);

    /*//////////////////////////////////////////////////////////////
                        WITHDRAWAL OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Processes token withdrawals from vault
     * @param token Token contract to withdraw
     * @param from Source of shares
     * @param to Recipient of tokens
     * @param amount Token amount (in base units, 0 for share-based)
     * @param share Share amount (0 for amount-based)
     * @return amountOut Actual tokens withdrawn
     * @return shareOut Actual shares burned
     * @dev Manages:
     * · Share burning
     * · Token transfers
     * · Balance updates
     *
     * Requirements:
     * · Valid token contract
     * · Sufficient shares
     * · Either amount or share > 0
     * · Authorized withdrawal
     *
     * Security:
     * · Validates balances
     * · Checks permissions
     * · Updates state atomically
     */
    function withdraw(
        IERC20Custom token,
        address from,
        address to,
        uint256 amount,
        uint256 share
    ) external returns (uint256 amountOut, uint256 shareOut);

    /*//////////////////////////////////////////////////////////////
                        SHARE TRANSFERS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Transfers vault shares between accounts
     * @param token Associated token contract
     * @param from Source of shares
     * @param to Recipient of shares
     * @param share Amount of shares to transfer
     * @dev Executes:
     * · Direct share movement
     * · Balance updates
     * · Event emission
     *
     * Requirements:
     * · Sufficient share balance
     * · Valid addresses
     * · Share amount > 0
     *
     * Note: Bypasses amount calculations for efficiency
     */
    function transfer(
        IERC20Custom token,
        address from,
        address to,
        uint256 share
    ) external;

    /*//////////////////////////////////////////////////////////////
                        BALANCE QUERIES
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Retrieves account's vault share balance
     * @param token Token contract to query
     * @param account Address to check
     * @return uint256 Share balance
     * @dev Provides:
     * · Raw share balance
     * · Without conversion
     * · Current state
     *
     * Use toAmount() to convert to token amount
     */
    function balanceOf(
        IERC20Custom token,
        address account
    ) external view returns (uint256);

    /*//////////////////////////////////////////////////////////////
                        CONVERSION OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Converts token amount to vault shares
     * @param token Token contract for conversion
     * @param amount Amount of tokens to convert
     * @param roundUp Whether to round up result
     * @return share Equivalent share amount
     * @dev Calculates:
     * · Share equivalent
     * · Based on totals
     * · Handles precision
     *
     * Rounding:
     * true = ceiling (≥)
     * false = floor (≤)
     */
    function toShare(
        IERC20Custom token,
        uint256 amount,
        bool roundUp
    ) external view returns (uint256 share);

    /**
     * @notice Converts vault shares to token amount
     * @param token Token contract for conversion
     * @param share Amount of shares to convert
     * @param roundUp Whether to round up result
     * @return amount Equivalent token amount
     * @dev Calculates:
     * · Token equivalent
     * · Based on totals
     * · Handles precision
     *
     * Rounding:
     * true = ceiling (≥)
     * false = floor (≤)
     */
    function toAmount(
        IERC20Custom token,
        uint256 share,
        bool roundUp
    ) external view returns (uint256 amount);

    /**
     * @notice Gets the list of active controllers
     * @return Array of controller addresses
     */
    function getControllers() external view returns (address[] memory);

    /*//////////////////////////////////////////////////////////////
                            VAULT TOTALS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Retrieves vault's total supply tracking
     * @param token Token contract to query
     * @return vaultTotals Rebase struct containing:
     * · elastic: Total token amount
     * · base: Total shares
     * @dev Provides:
     * · Current vault state
     * · Supply tracking
     * · Conversion basis
     *
     * Used for:
     * · Share calculations
     * · Amount conversions
     * · State validation
     */
    function totals(
        IERC20Custom token
    ) external view returns (Rebase memory vaultTotals);
}

File 32 of 33 : IVoteEscrowedSTTX.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

/**
 * @title IVoteEscrowedSTTX
 * @dev Interface for vote-escrowed STTX (veSTTX) token operations
 * @notice Defines functionality for:
 * 1. Token withdrawal management
 * 2. Escrow position handling
 * 3. Voting power release
 */
interface IVoteEscrowedSTTX {
    /*//////////////////////////////////////////////////////////////
                        WITHDRAWAL OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Processes withdrawal of escrowed STTX tokens
     * @dev Handles:
     * · Lock period verification
     * · Position liquidation
     * · Token transfers
     *
     * Requirements:
     * · Lock period expired
     * · Active position exists
     * · Caller is position owner
     *
     * Effects:
     * · Releases locked tokens
     * · Removes voting power
     * · Clears escrow position
     */
    function withdraw() external;
}

File 33 of 33 : AuxRebase.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.24 <0.9.0;

/**
 * @title Rebase Library
 * @dev Library for handling elastic supply token calculations and adjustments
 * @notice This library provides mathematical operations for elastic/base token conversions
 * and supply adjustments. It handles two key concepts:
 *
 * 1. Elastic Supply: The actual total supply that can expand or contract
 * 2. Base Supply: The underlying base amount that remains constant
 */
/*//////////////////////////////////////////////////////////////
                               TYPES
//////////////////////////////////////////////////////////////*/
/**
 * @dev Core data structure for elastic supply tracking
 * @param elastic Current elastic (rebased) supply
 * @param base Current base (non-rebased) supply
 */
struct Rebase {
    uint256 elastic;
    uint256 base;
}

/**
 * @title AuxRebase
 * @dev Auxiliary functions for elastic supply calculations
 * @notice Provides safe mathematical operations for elastic/base conversions
 * with optional rounding control
 */
library AuxRebase {
    /*//////////////////////////////////////////////////////////////
                         ELASTIC SUPPLY OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Increases the elastic supply
     * @param total Current total supply state
     * @param elastic Amount to add to elastic supply
     * @return newElastic Updated elastic supply after addition
     */
    function addElastic(
        Rebase storage total,
        uint256 elastic
    ) internal returns (uint256 newElastic) {
        newElastic = total.elastic += elastic;
    }

    /**
     * @notice Decreases the elastic supply
     * @param total Current total supply state
     * @param elastic Amount to subtract from elastic supply
     * @return newElastic Updated elastic supply after subtraction
     */
    function subElastic(
        Rebase storage total,
        uint256 elastic
    ) internal returns (uint256 newElastic) {
        newElastic = total.elastic -= elastic;
    }

    /*//////////////////////////////////////////////////////////////
                         CONVERSION OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Converts an elastic amount to its base amount
     * @param total Current total supply state
     * @param elastic Amount of elastic tokens to convert
     * @param roundUp If true, rounds up the result
     * @return base Equivalent amount in base units
     * @dev
     * · If elastic supply is 0, returns elastic amount as base
     * · Handles potential precision loss during conversion
     * · Rounding can cause slight variations in converted amounts
     * · Recommended for scenarios requiring precise supply tracking
     *
     * Rounding Behavior:
     * · roundUp = false: Always rounds down (truncates)
     * · roundUp = true: Rounds up if there's a fractional remainder
     *
     * Edge Cases:
     * · total.elastic == 0: Returns input elastic as base
     * · Potential for minimal precision differences
     */
    function toBase(
        Rebase memory total,
        uint256 elastic,
        bool roundUp
    ) internal pure returns (uint256 base) {
        if (total.elastic == 0) {
            base = elastic;
        } else {
            base = (elastic * total.base) / total.elastic;
            if (roundUp && (base * total.elastic) / total.base < elastic) {
                base++;
            }
        }
    }

    /**
     * @notice Converts a base amount to its elastic amount
     * @param total Current total supply state
     * @param base Amount of base tokens to convert
     * @param roundUp If true, rounds up the result
     * @return elastic Equivalent amount in elastic units
     * @dev
     * · If base supply is 0, returns base amount as elastic
     * · Handles potential precision loss during conversion
     * · Rounding can cause slight variations in converted amounts
     * · Recommended for scenarios requiring precise supply tracking
     *
     * Rounding Behavior:
     * · roundUp = false: Always rounds down (truncates)
     * · roundUp = true: Rounds up if there's a fractional remainder
     *
     * Edge Cases:
     * · total.base == 0: Returns input base as elastic
     * · Potential for minimal precision differences
     */
    function toElastic(
        Rebase memory total,
        uint256 base,
        bool roundUp
    ) internal pure returns (uint256 elastic) {
        if (total.base == 0) {
            elastic = base;
        } else {
            elastic = (base * total.elastic) / total.base;
            if (roundUp && (elastic * total.base) / total.elastic < base) {
                elastic++;
            }
        }
    }

    /*//////////////////////////////////////////////////////////////
                         COMBINED OPERATIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Adds elastic tokens and calculates corresponding base amount
     * @param total Current total supply state
     * @param elastic Amount of elastic tokens to add
     * @param roundUp If true, rounds up base conversion
     * @return (Rebase, uint256) Updated total supply and calculated base amount
     */
    function add(
        Rebase memory total,
        uint256 elastic,
        bool roundUp
    ) internal pure returns (Rebase memory, uint256 base) {
        base = toBase(total, elastic, roundUp);
        total.elastic += elastic;
        total.base += base;
        return (total, base);
    }

    /**
     * @notice Subtracts base tokens and calculates corresponding elastic amount
     * @param total Current total supply state
     * @param base Amount of base tokens to subtract
     * @param roundUp If true, rounds up elastic conversion
     * @return (Rebase, uint256) Updated total supply and calculated elastic amount
     */
    function sub(
        Rebase memory total,
        uint256 base,
        bool roundUp
    ) internal pure returns (Rebase memory, uint256 elastic) {
        elastic = toElastic(total, base, roundUp);
        total.elastic -= elastic;
        total.base -= base;
        return (total, elastic);
    }

    /**
     * @notice Adds specific amounts to both elastic and base supplies
     * @param total Current total supply state
     * @param elastic Amount of elastic tokens to add
     * @param base Amount of base tokens to add
     * @return Rebase Updated total supply after addition
     */
    function add(
        Rebase memory total,
        uint256 elastic,
        uint256 base
    ) internal pure returns (Rebase memory) {
        total.elastic += elastic;
        total.base += base;
        return total;
    }

    /**
     * @notice Subtracts specific amounts from both elastic and base supplies
     * @param total Current total supply state
     * @param elastic Amount of elastic tokens to subtract
     * @param base Amount of base tokens to subtract
     * @return Rebase Updated total supply after subtraction
     */
    function sub(
        Rebase memory total,
        uint256 elastic,
        uint256 base
    ) internal pure returns (Rebase memory) {
        total.elastic -= elastic;
        total.base -= base;
        return total;
    }
}

Settings
{
  "viaIR": true,
  "evmVersion": "paris",
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "metadata": {
    "useLiteralContent": true
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"contract IBaseContracts","name":"baseContracts_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"InsufficientAllowance","type":"error"},{"inputs":[],"name":"InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"InvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"InvalidSpender","type":"error"},{"inputs":[],"name":"InvalidWithdrawalDelay","type":"error"},{"inputs":[],"name":"InvalidWithdrawalWindow","type":"error"},{"inputs":[],"name":"ReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"SpenderNotAuthorized","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"UnauthorizedAccount","type":"error"},{"inputs":[],"name":"WithdrawalNotInitiated","type":"error"},{"inputs":[],"name":"WithdrawalWindowAlreadyClosed","type":"error"},{"inputs":[],"name":"WithdrawalWindowNotOpenYet","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroAmount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"spender","type":"address"}],"name":"SpenderApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"spender","type":"address"}],"name":"SpenderRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawalCompleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newDelay","type":"uint256"}],"name":"WithdrawalDelayDecreased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"WithdrawalInitiated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newWindow","type":"uint256"}],"name":"WithdrawalWindowIncreased","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"approveSpender","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"approvedSpenders","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"beginWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"newDelay","type":"uint256"}],"name":"decreaseWithdrawalDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getCurrentAndNextWithdrawalSlots","outputs":[{"internalType":"uint256","name":"currentSlot","type":"uint256"},{"internalType":"uint256","name":"currentAmount","type":"uint256"},{"internalType":"uint256","name":"nextSlot","type":"uint256"},{"internalType":"uint256","name":"nextAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"time","type":"uint256"}],"name":"getWithdrawalSlot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"slot","type":"uint256"}],"name":"getWithdrawalSlotAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"}],"name":"getWithdrawalSlotRange","outputs":[{"internalType":"uint256[]","name":"slots","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getWithdrawalStatus","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"bool","name":"isWithdrawable","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newWindow","type":"uint256"}],"name":"increaseWithdrawalWindow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"isApprovedSpender","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"revokeSpender","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sttx","outputs":[{"internalType":"contract IERC20TokenRebase","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"withdrawalAmounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"withdrawalSlots","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"withdrawalTimestamps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalWindow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

60a06040523462000056576200001f6200001862000254565b91620006ab565b620000296200005c565b612956620009f28239608051818181610da3015281816114c70152818161153b0152611763015261295690f35b62000062565b60405190565b600080fd5b601f801991011690565b634e487b7160e01b600052604160045260246000fd5b90620000939062000067565b810190811060018060401b03821117620000ac57604052565b62000071565b90620000c9620000c16200005c565b928362000087565b565b600080fd5b600080fd5b600080fd5b600080fd5b60018060401b038111620000fe57620000fa60209162000067565b0190565b62000071565b60005b83811062000119575050906000910152565b80602091830151818501520162000107565b90929192620001446200013e82620000df565b620000b2565b938185526020850190828401116200016357620001619262000104565b565b620000da565b9080601f830112156200018a5781602062000187935191016200012b565b90565b620000d5565b60018060a01b031690565b620001a69062000190565b90565b620001b4906200019b565b90565b620001c281620001a9565b03620001ca57565b600080fd5b90505190620001de82620001b7565b565b90916060828403126200024e57600082015160018060401b0381116200024857836200020e91840162000169565b9260208301519060018060401b038211620002425762000235816200023f93860162000169565b93604001620001cf565b90565b620000d0565b620000d0565b620000cb565b6200027762003348803803806200026b81620000b2565b928339810190620001e0565b909192565b60001b90565b9062000291600019916200027c565b9181191691161790565b90565b90565b90565b620002bd620002b7620002c3926200029b565b620002a1565b6200029e565b90565b90565b90620002e3620002dd620002eb92620002a4565b620002c6565b825462000282565b9055565b90565b6200030b620003056200031192620002ef565b620002a1565b6200029e565b90565b906200032e620003286200033692620002f2565b620002c6565b825462000282565b9055565b620003536200034d620003599262000190565b620002a1565b62000190565b90565b62000367906200033a565b90565b62000375906200035c565b90565b60e01b90565b62000389906200019b565b90565b62000397816200037e565b036200039f57565b600080fd5b90505190620003b3826200038c565b565b90602082820312620003d257620003cf91600001620003a4565b90565b620000cb565b60000190565b620003e86200005c565b3d6000823e3d90fd5b620003fd90516200037e565b90565b6200040b906200035c565b90565b5190565b634e487b7160e01b600052602260045260246000fd5b90600160028304921680156200044b575b60208310146200044557565b62000412565b91607f169162000439565b600052602060002090565b601f602091010490565b1b90565b919060086200048f91029162000488600019846200046b565b926200046b565b9181191691161790565b620004b2620004ac620004b8926200029e565b620002a1565b6200029e565b90565b9190620004d6620004d0620004df9362000499565b620002c6565b9083546200046f565b9055565b600090565b620004fe91620004f7620004e3565b91620004bb565b565b5b8181106200050d575050565b806200051d6000600193620004e8565b0162000501565b9190601f811162000535575b505050565b620005446200056f9362000456565b906020620005528462000461565b8301931062000578575b620005679062000461565b019062000500565b38808062000530565b915062000567819290506200055c565b1c90565b906200059f906000199060080262000588565b191690565b81620005b0916200058c565b906002021790565b90620005c4816200040e565b9060018060401b0382116200069757620005eb82620005e4855462000428565b8562000524565b602090601f83116001146200062557918091620006139360009262000618575b5050620005a4565b90555b565b909150015138806200060b565b601f19831691620006368562000456565b9260005b8181106200067e5750916002939185600196941062000661575b5050500201905562000616565b62000673910151601f8416906200058c565b905538808062000654565b919360206001819287870151815501950192016200063a565b62000071565b90620006a991620005b8565b565b916020620006fc6200071592620006c1620007b7565b620006d162093a806007620002c9565b620006e162012750600862000314565b620006f6620006f0826200036a565b62000894565b6200036a565b63ec4d8019906200070c6200005c565b93849262000378565b825281806200072760048201620003d8565b03915afa928315620007b1576200077a9362000772926000916200077c575b506080526200076a620007646200075e6080620003f1565b62000400565b62000894565b60026200069d565b60036200069d565b565b620007a2915060203d8111620007a9575b62000799818362000087565b810190620003b5565b3862000746565b503d6200078d565b620003de565b620007c1620007c3565b565b620007cd62000829565b565b90565b620007eb620007e5620007f192620007cf565b620002a1565b6200029e565b90565b620008006001620007d2565b90565b906200081d62000817620008259262000499565b620002c6565b825462000282565b9055565b620008336200084b565b6200084962000841620007f4565b600162000803565b565b6200085f62000859620008e9565b62000984565b565b90565b6200087d62000877620008839262000861565b620002a1565b62000190565b90565b620008919062000864565b90565b620008b5620008ae620008a8600062000886565b6200019b565b916200019b565b14620008bd57565b620008c76200005c565b63d92e233d60e01b815280620008e060048201620003d8565b0390fd5b600090565b620008f3620008e4565b503390565b60001c90565b60018060a01b031690565b620009186200091e91620008f8565b620008fe565b90565b6200092d905462000909565b90565b906200094360018060a01b03916200027c565b9181191691161790565b62000958906200035c565b90565b90565b90620009786200097262000980926200094d565b6200095b565b825462000930565b9055565b62000990600062000921565b6200099d8260006200095e565b90620009d5620009ce7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0936200094d565b916200094d565b91620009e06200005c565b80620009ec81620003d8565b0390a356fe60806040526004361015610013575b610e5c565b61001e60003561021d565b806306fdde0314610218578063095ea7b314610213578063099a0aae1461020e578063141ebd831461020957806318160ddd146102045780632366f298146101ff57806323b872dd146101fa578063313ce567146101f5578063382e7244146101f0578063399231e3146101eb5780633ccfd60b146101e657806347e7ef24146101e15780635bb5d99d146101dc5780635dea7556146101d757806370a08231146101d2578063715018a6146101cd5780637491687e146101c857806375b8b52f146101c357806380c62199146101be5780638da5cb5b146101b957806395d89b41146101b4578063a3760758146101af578063a3ef270b146101aa578063a7ab6961146101a5578063a9059cbb146101a0578063ae76cf2a1461019b578063c303a6a714610196578063c7f71b8a14610191578063d19bd0a71461018c578063dd62ed3e14610187578063ec4d8019146101825763f2fde38b0361000e57610e29565b610df4565b610d6b565b610d08565b610cc3565b610c8e565b610c5b565b610c25565b610bf0565b610bab565b610b76565b610b27565b610af2565b610a9c565b610a69565b610a31565b6109cb565b610996565b61095f565b61084a565b610816565b6107e3565b6107ae565b61070c565b610679565b61061a565b6105a6565b610532565b6104fd565b610411565b6103b6565b6102c9565b60e01c90565b60405190565b600080fd5b600080fd5b600091031261023e57565b61022e565b5190565b60209181520190565b60005b838110610264575050906000910152565b806020918301518185015201610253565b601f801991011690565b61029e6102a76020936102ac9361029581610243565b93848093610247565b95869101610250565b610275565b0190565b6102c6916020820191600081840391015261027f565b90565b346102f9576102d9366004610233565b6102f56102e4610fc3565b6102ec610223565b918291826102b0565b0390f35b610229565b60018060a01b031690565b610312906102fe565b90565b61031e81610309565b0361032557565b600080fd5b9050359061033782610315565b565b90565b61034581610339565b0361034c57565b600080fd5b9050359061035e8261033c565b565b9190604083820312610389578061037d610386926000860161032a565b93602001610351565b90565b61022e565b151590565b61039c9061038e565b9052565b91906103b490600060208501940190610393565b565b346103e7576103e36103d26103cc366004610360565b90610fde565b6103da610223565b918291826103a0565b0390f35b610229565b90602082820312610406576104039160000161032a565b90565b61022e565b60000190565b3461043f576104296104243660046103ec565b6110f8565b610431610223565b8061043b8161040b565b0390f35b610229565b90565b61045b610456610460926102fe565b610444565b6102fe565b90565b61046c90610447565b90565b61047890610463565b90565b906104859061046f565b600052602052604060002090565b1c90565b90565b6104aa9060086104af9302610493565b610497565b90565b906104bd915461049a565b90565b6104d7906104d2600a9160009261047b565b6104b2565b90565b6104e390610339565b9052565b91906104fb906000602085019401906104da565b565b3461052d576105296105186105133660046103ec565b6104c0565b610520610223565b918291826104e7565b0390f35b610229565b3461056257610542366004610233565b61055e61054d61112f565b610555610223565b918291826104e7565b0390f35b610229565b61059d6105a494610593606094989795610589608086019a60008701906104da565b60208501906104da565b60408301906104da565b01906104da565b565b346105da576105b6366004610233565b6105d66105c161119f565b906105cd949294610223565b94859485610567565b0390f35b610229565b9091606082840312610615576106126105fb846000850161032a565b93610609816020860161032a565b93604001610351565b90565b61022e565b3461064b576106476106366106303660046105df565b9161120d565b61063e610223565b918291826103a0565b0390f35b610229565b60ff1690565b61065f90610650565b9052565b919061067790600060208501940190610656565b565b346106a957610689366004610233565b6106a561069461126d565b61069c610223565b91829182610663565b0390f35b610229565b906106b89061046f565b600052602052604060002090565b60ff1690565b6106dc9060086106e19302610493565b6106c6565b90565b906106ef91546106cc565b90565b61070990610704600c916000926106ae565b6106e4565b90565b3461073c576107386107276107223660046103ec565b6106f2565b61072f610223565b918291826103a0565b0390f35b610229565b9060208282031261075b5761075891600001610351565b90565b61022e565b61077461076f61077992610339565b610444565b610339565b90565b9061078690610760565b600052602052604060002090565b6107ab906107a6600b9160009261077c565b6104b2565b90565b346107de576107da6107c96107c4366004610741565b610794565b6107d1610223565b918291826104e7565b0390f35b610229565b34610811576107f3366004610233565b6107fb6116ce565b610803610223565b8061080d8161040b565b0390f35b610229565b346108455761082f610829366004610360565b906117ff565b610837610223565b806108418161040b565b0390f35b610229565b346108785761086261085d366004610741565b6118a9565b61086a610223565b806108748161040b565b0390f35b610229565b91906040838203126108a6578061089a6108a39260008601610351565b93602001610351565b90565b61022e565b5190565b60209181520190565b60200190565b6108c790610339565b9052565b906108d8816020936108be565b0190565b60200190565b906108ff6108f96108f2846108ab565b80936108af565b926108b8565b9060005b8181106109105750505090565b90919261092961092360019286516108cb565b946108dc565b9101919091610903565b909161094e61095c93604084019084820360008601526108e2565b9160208184039101526108e2565b90565b346109915761097861097236600461087d565b90611981565b9061098d610984610223565b92839283610933565b0390f35b610229565b346109c6576109c26109b16109ac3660046103ec565b611a5b565b6109b9610223565b918291826104e7565b0390f35b610229565b346109f9576109db366004610233565b6109e3611aa0565b6109eb610223565b806109f58161040b565b0390f35b610229565b604090610a28610a2f9496959396610a1e606084019860008501906104da565b60208301906104da565b0190610393565b565b34610a6457610a60610a4c610a473660046103ec565b611aaa565b610a57939193610223565b938493846109fe565b0390f35b610229565b34610a9757610a81610a7c366004610741565b611bfc565b610a89610223565b80610a938161040b565b0390f35b610229565b34610aca57610ab4610aaf366004610741565b611d5c565b610abc610223565b80610ac68161040b565b0390f35b610229565b610ad890610309565b9052565b9190610af090600060208501940190610acf565b565b34610b2257610b02366004610233565b610b1e610b0d611d98565b610b15610223565b91829182610adc565b0390f35b610229565b34610b5757610b37366004610233565b610b53610b42611dae565b610b4a610223565b918291826102b0565b0390f35b610229565b610b7390610b6e60099160009261047b565b6104b2565b90565b34610ba657610ba2610b91610b8c3660046103ec565b610b5c565b610b99610223565b918291826104e7565b0390f35b610229565b34610bdb57610bd7610bc6610bc1366004610741565b611dfc565b610bce610223565b918291826104e7565b0390f35b610229565b610bed60076000906104b2565b90565b34610c2057610c00366004610233565b610c1c610c0b610be0565b610c13610223565b918291826104e7565b0390f35b610229565b34610c5657610c52610c41610c3b366004610360565b90611e1c565b610c49610223565b918291826103a0565b0390f35b610229565b34610c8957610c73610c6e3660046103ec565b611eb2565b610c7b610223565b80610c858161040b565b0390f35b610229565b34610cbe57610cba610ca9610ca43660046103ec565b611ede565b610cb1610223565b918291826103a0565b0390f35b610229565b34610cf357610cef610cde610cd9366004610741565b611efd565b610ce6610223565b918291826104e7565b0390f35b610229565b610d0560086000906104b2565b90565b34610d3857610d18366004610233565b610d34610d23610cf8565b610d2b610223565b918291826104e7565b0390f35b610229565b9190604083820312610d665780610d5a610d63926000860161032a565b9360200161032a565b90565b61022e565b34610d9c57610d98610d87610d81366004610d3d565b90611f34565b610d8f610223565b918291826104e7565b0390f35b610229565b7f000000000000000000000000000000000000000000000000000000000000000090565b610dce90610463565b90565b610dda90610dc5565b9052565b9190610df290600060208501940190610dd1565b565b34610e2457610e04366004610233565b610e20610e0f610da1565b610e17610223565b91829182610dde565b0390f35b610229565b34610e5757610e41610e3c3660046103ec565b611fca565b610e49610223565b80610e538161040b565b0390f35b610229565b600080fd5b606090565b634e487b7160e01b600052602260045260246000fd5b9060016002830492168015610e9c575b6020831014610e9757565b610e66565b91607f1691610e8c565b60209181520190565b600052602060002090565b9060009291805490610ed5610ece83610e7c565b8094610ea6565b91600181169081600014610f2e5750600114610ef1575b505050565b610efe9192939450610eaf565b916000925b818410610f165750500190388080610eec565b60018160209295939554848601520191019290610f03565b92949550505060ff1916825215156020020190388080610eec565b90610f5391610eba565b90565b634e487b7160e01b600052604160045260246000fd5b90610f7690610275565b810190811067ffffffffffffffff821117610f9057604052565b610f56565b90610fb5610fae92610fa5610223565b93848092610f49565b0383610f6c565b565b610fc090610f95565b90565b610fcb610e61565b50610fd66002610fb7565b90565b600090565b610fe6610fd9565b50610ff9610ff382611ede565b1561038e565b6110165761101191611009611fd5565b919091611fe2565b600190565b61101e610223565b633b09f10560e01b8152806110356004820161040b565b0390fd5b61104a90611045611ff2565b611097565b565b60001b90565b9061105e60ff9161104c565b9181191691161790565b6110719061038e565b90565b90565b9061108c61108761109392611068565b611074565b8254611052565b9055565b6110a081612047565b6110b660016110b1600c84906106ae565b611077565b6110e07f3584ac55fd91fcf5efce973892cccf98c9b1bc944e64135fc1b93132a8e3933e9161046f565b906110e9610223565b806110f38161040b565b0390a2565b61110190611039565b565b600090565b60001c90565b61111a61111f91611108565b610497565b90565b61112c905461110e565b90565b611137611103565b506111426004611122565b90565b90565b61115c61115761116192611145565b610444565b610339565b90565b634e487b7160e01b600052601160045260246000fd5b61118961118f91939293610339565b92610339565b820180921161119a57565b611164565b6111a7611103565b506111b0611103565b506111b9611103565b506111c2611103565b506111cc42611dfc565b906111e1826111db6001611148565b9061117a565b6111f56111f0600b859061077c565b611122565b9161120a611205600b849061077c565b611122565b90565b916112379261121a610fd9565b5061122f611226611fd5565b829084916120cd565b919091612162565b600190565b600090565b90565b61125861125361125d92611241565b610444565b610650565b90565b61126a6012611244565b90565b61127561123c565b5061127e611260565b90565b61128961223d565b611291611385565b6112996122a9565b565b90565b6112b26112ad6112b79261129b565b610444565b610339565b90565b906112c76000199161104c565b9181191691161790565b90565b906112e96112e46112f092610760565b6112d1565b82546112ba565b9055565b61130361130991939293610339565b92610339565b820391821161131457565b611164565b600080fd5b60e01b90565b600091031261132f57565b61022e565b61133c610223565b3d6000823e3d90fd5b61134e90610447565b90565b61135a90611345565b90565b61137161136c6113769261129b565b610444565b6102fe565b90565b6113829061135d565b90565b61138d611fd5565b42906113a361139e600a839061047b565b611122565b91826113b86113b2600061129e565b91610339565b146116ab57806113d06113ca85610339565b91610339565b1115611688576113fb6113f56113f0856113ea6008611122565b9061117a565b610339565b91610339565b1015611665576114156114106009839061047b565b611122565b918261143161142b61142685611a5b565b610339565b91610339565b11611642576114419083906122bd565b61145f61144e600061129e565b61145a600a849061047b565b6112d4565b61147d61146c600061129e565b6114786009849061047b565b6112d4565b6114a58261149f6114906005859061047b565b9161149a83611122565b6112f4565b906112d4565b6114c26114bb836114b66004611122565b6112f4565b60046112d4565b6114eb7f0000000000000000000000000000000000000000000000000000000000000000610dc5565b63af14052c90803b1561163d5761150f91600091611507610223565b93849261131e565b82528183816115206004820161040b565b03925af180156116385761160b575b5061156c61156461155f7f0000000000000000000000000000000000000000000000000000000000000000610dc5565b611351565b8284916123db565b8082906115ae61159c7f1a39b9c5044b9f0ff56c5951e30c1ebe24911353aafcceb9250e83a24fe158c49261046f565b926115a5610223565b918291826104e7565b0390a2906115bc6000611379565b90916116066115f46115ee7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9361046f565b9361046f565b936115fd610223565b918291826104e7565b0390a3565b61162b9060003d8111611631575b6116238183610f6c565b810190611324565b3861152f565b503d611619565b611334565b611319565b61164a610223565b631e9acf1760e31b8152806116616004820161040b565b0390fd5b61166d610223565b63dbe67dcd60e01b8152806116846004820161040b565b0390fd5b611690610223565b6360fc88b360e11b8152806116a76004820161040b565b0390fd5b6116b3610223565b630b781b4d60e31b8152806116ca6004820161040b565b0390fd5b6116d6611281565b565b906116ea916116e561223d565b611700565b6116f26122a9565b565b6116fd90610463565b90565b9061170a82612047565b61171381612429565b61173b816117356117266005869061047b565b9161173083611122565b61117a565b906112d4565b6117586117518261174c6004611122565b61117a565b60046112d4565b6117a561178c6117877f0000000000000000000000000000000000000000000000000000000000000000610dc5565b611351565b611794611fd5565b61179d306116f4565b908492612499565b6117af6000611379565b9190916117fa6117e86117e27fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9361046f565b9361046f565b936117f1610223565b918291826104e7565b0390a3565b90611809916116d8565b565b61181c90611817611ff2565b61181e565b565b8061183a61183461182f6007611122565b610339565b91610339565b10156118865761184b8160076112d4565b6118817f6f3e5d6a00b186747b385d5be1e4e88c163f2541c4a63e9ecbb55ba29d44670b91611878610223565b918291826104e7565b0390a1565b61188e610223565b633cb2b8d760e11b8152806118a56004820161040b565b0390fd5b6118b29061180b565b565b606090565b906118cc6118c5610223565b9283610f6c565b565b67ffffffffffffffff81116118e65760208091020190565b610f56565b906118fd6118f8836118ce565b6118b9565b918252565b369037565b9061192c611914836118eb565b9260208061192286936118ce565b9201910390611902565b565b600161193a9101610339565b90565b634e487b7160e01b600052603260045260246000fd5b9061195d826108ab565b81101561196e576020809102010190565b61193d565b9061197d90610339565b9052565b6119b56119ae6119a86119c5939594956119996118b4565b506119a26118b4565b50611dfc565b94611dfc565b84906112f4565b6119bf6001611148565b9061117a565b906119cf82611907565b926119d983611907565b916119e4600061129e565b5b806119f86119f287610339565b91610339565b1015611a5457611a4f90611a4a611a38611a33611a1687859061117a565b611a2c81611a278d91889092611953565b611973565b600b61077c565b611122565b611a458791849092611953565b611973565b61192e565b6119e5565b5091925050565b611a72611a7791611a6a611103565b50600561047b565b611122565b90565b611a82611ff2565b611a8a611a8c565b565b611a9e611a996000611379565b612527565b565b611aa8611a7a565b565b90611ab3611103565b50611abc611103565b50611ac5610fd9565b50611aed611ae8611ae0611adb6009869061047b565b611122565b93600a61047b565b611122565b904282611b03611afd600061129e565b91610339565b141580611b44575b9081611b16575b5090565b9050611b3d611b37611b3285611b2c6008611122565b9061117a565b610339565b91610339565b1038611b12565b5080611b58611b5285610339565b91610339565b11611b0b565b611b6f90611b6a611ff2565b611b71565b565b80611b8d611b87611b826008611122565b610339565b91610339565b1115611bd957611b9e8160086112d4565b611bd47f176d9d2c8f84a996862e9cb6ae03eb576184e3fb7621bcbfc6e1828f4b11468091611bcb610223565b918291826104e7565b0390a1565b611be1610223565b6325d4924760e01b815280611bf86004820161040b565b0390fd5b611c0590611b5e565b565b611c1890611c1361223d565b611c46565b611c206122a9565b565b916020611c44929493611c3d604082019660008301906104da565b01906104da565b565b611c4f81612429565b611c57611fd5565b9080611c73611c6d611c6885611a5b565b610339565b91610339565b11611d3957611ca9611c8f611c8a600a859061047b565b611122565b611ca3611c9e6009869061047b565b611122565b906122bd565b611cbd42611cb76007611122565b9061117a565b91611cd383611cce600a849061047b565b6112d4565b611ce882611ce36009849061047b565b6112d4565b611cf3838390612588565b9091611d1f7f31f69201fab7912e3ec9850e3ab705964bf46d9d4276bdcbb6d05e965e5f54019261046f565b92611d34611d2b610223565b92839283611c22565b0390a2565b611d41610223565b631e9acf1760e31b815280611d586004820161040b565b0390fd5b611d6590611c07565b565b600090565b60018060a01b031690565b611d83611d8891611108565b611d6c565b90565b611d959054611d77565b90565b611da0611d67565b50611dab6000611d8b565b90565b611db6610e61565b50611dc16003610fb7565b90565b634e487b7160e01b600052601260045260246000fd5b611de6611dec91610339565b91610339565b908115611df7570490565b611dc4565b611e1990611e08611103565b50611e136008611122565b90611dda565b90565b611e3991611e28610fd9565b50611e31611fd5565b919091612162565b600190565b611e4f90611e4a611ff2565b611e51565b565b611e5a81612047565b611e706000611e6b600c84906106ae565b611077565b611e9a7f124b4488f16f954d5626769cbcab59a035cff89968908f4bbb90c264efcc9b839161046f565b90611ea3610223565b80611ead8161040b565b0390a2565b611ebb90611e3e565b565b611ec9611ece91611108565b6106c6565b90565b611edb9054611ebd565b90565b611ef5611efa91611eed610fd9565b50600c6106ae565b611ed1565b90565b611f14611f1991611f0c611103565b50600b61077c565b611122565b90565b90611f269061046f565b600052602052604060002090565b611f5991611f4f611f5492611f47611103565b506006611f1c565b61047b565b611122565b90565b611f6d90611f68611ff2565b611f6f565b565b80611f8b611f85611f806000611379565b610309565b91610309565b14611f9b57611f9990612527565b565b611fc6611fa86000611379565b611fb0610223565b91829163b20f76e360e01b835260048301610adc565b0390fd5b611fd390611f5c565b565b611fdd611d67565b503390565b91611ff092916001926125b9565b565b611ffa611d98565b61201361200d612008611fd5565b610309565b91610309565b0361201a57565b612043612025611fd5565b61202d610223565b9182916332b2baa360e01b835260048301610adc565b0390fd5b61206261205c6120576000611379565b610309565b91610309565b1461206957565b612071610223565b63d92e233d60e01b8152806120886004820161040b565b0390fd5b6040906120b66120bd94969593966120ac60608401986000850190610acf565b60208301906104da565b01906104da565b565b906120ca9103610339565b90565b9291926120db818390611f34565b90816120f16120eb600019610339565b91610339565b036120fe575b5050509050565b8161211161210b87610339565b91610339565b106121385761212f93946121269193926120bf565b906000926125b9565b803880806120f7565b5061215e84929192612148610223565b938493630c95cf2760e11b85526004850161208c565b0390fd5b918261217f6121796121746000611379565b610309565b91610309565b146121e257816121a061219a6121956000611379565b610309565b91610309565b146121b3576121b1929190916126e8565b565b6121de6121c06000611379565b6121c8610223565b918291639cfea58360e01b835260048301610adc565b0390fd5b61220d6121ef6000611379565b6121f7610223565b9182916313053d9360e21b835260048301610adc565b0390fd5b90565b61222861222361222d92612211565b610444565b610339565b90565b61223a6002612214565b90565b6122476001611122565b61226061225a612255612230565b610339565b91610339565b1461227957612277612270612230565b60016112d4565b565b612281610223565b6306fda65d60e31b8152806122986004820161040b565b0390fd5b6122a66001611148565b90565b6122bb6122b461229c565b60016112d4565b565b806122d16122cb600061129e565b91610339565b14801561235f575b61235b576122e690611dfc565b8161230c6123066123016122fc600b869061077c565b611122565b610339565b91610339565b1161233a576123326123236123389392600b61077c565b9161232d83611122565b6112f4565b906112d4565b565b612359915061235461234c600061129e565b91600b61077c565b6112d4565b565b5050565b508161237461236e600061129e565b91610339565b146122d9565b61238390610463565b90565b63ffffffff1690565b63ffffffff60e01b1690565b6123af6123aa6123b492612386565b61131e565b61238f565b90565b9160206123d99294936123d260408201966000830190610acf565b01906104da565b565b9061242261242793612413600494936123fa63a9059cbb91939161239b565b92612403610223565b96879460208601908152016123b7565b60208201810382520383610f6c565b61285f565b565b61243c612436600061129e565b91610339565b1461244357565b61244b610223565b631f2a200560e01b8152806124626004820161040b565b0390fd5b604090612490612497949695939661248660608401986000850190610acf565b6020830190610acf565b01906104da565b565b6004926124d36124e795936124e293946124ba6323b872dd9294919261239b565b936124c3610223565b9788956020870190815201612466565b60208201810382520383610f6c565b61285f565b565b906124fa60018060a01b039161104c565b9181191691161790565b90565b9061251c6125176125239261046f565b612504565b82546124e9565b9055565b6125316000611d8b565b61253c826000612507565b9061257061256a7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09361046f565b9161046f565b91612579610223565b806125838161040b565b0390a3565b906125b16125a261259b6125b794611dfc565b600b61077c565b916125ac83611122565b61117a565b906112d4565b565b9092816125d76125d16125cc6000611379565b610309565b91610309565b146126ab57836125f86125f26125ed6000611379565b610309565b91610309565b1461267c5761261c8361261761261060068690611f1c565b879061047b565b6112d4565b612626575b505050565b91909161267161265f6126597f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259361046f565b9361046f565b93612668610223565b918291826104e7565b0390a3388080612621565b6126a76126896000611379565b612691610223565b91829163270af7ed60e11b835260048301610adc565b0390fd5b6126d66126b86000611379565b6126c0610223565b9182916322f051b160e21b835260048301610adc565b0390fd5b906126e59101610339565b90565b919091806127076127016126fc6000611379565b610309565b91610309565b146000146127ec5761272c612725836127206004611122565b61117a565b60046112d4565b5b8261274961274361273e6000611379565b610309565b91610309565b146000146127bf5761276e612767836127626004611122565b6120bf565b60046112d4565b5b9190916127ba6127a86127a27fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9361046f565b9361046f565b936127b1610223565b918291826104e7565b0390a3565b6127e7826127e16127d26005879061047b565b916127dc83611122565b6126da565b906112d4565b61276f565b6128006127fb6005839061047b565b611122565b8061281361280d85610339565b91610339565b1061283c576128266128379184906120bf565b6128326005849061047b565b6112d4565b61272d565b612844610223565b631e9acf1760e31b81528061285b6004820161040b565b0390fd5b90600060209161286d611103565b50612876611103565b50828151910182855af115612914573d6000519061289d612897600061129e565b91610339565b146000146128fa57506128af8161237a565b3b6128c36128bd600061129e565b91610339565b145b6128cc5750565b6128d86128f69161237a565b6128e0610223565b918291635274afe760e01b835260048301610adc565b0390fd5b61290d6129076001611148565b91610339565b14156128c5565b6040513d6000823e3d90fdfea2646970667358221220e1a4ec787be00dfee0d5b9ed40777c22695e50c3eb61d50a0bc226c769df91d564736f6c63430008180033000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000005ce899aed04c656776148fc3b1adbe59e5f13d5c0000000000000000000000000000000000000000000000000000000000000012566f74652d457363726f7765642053545458000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000067665535454580000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x60806040526004361015610013575b610e5c565b61001e60003561021d565b806306fdde0314610218578063095ea7b314610213578063099a0aae1461020e578063141ebd831461020957806318160ddd146102045780632366f298146101ff57806323b872dd146101fa578063313ce567146101f5578063382e7244146101f0578063399231e3146101eb5780633ccfd60b146101e657806347e7ef24146101e15780635bb5d99d146101dc5780635dea7556146101d757806370a08231146101d2578063715018a6146101cd5780637491687e146101c857806375b8b52f146101c357806380c62199146101be5780638da5cb5b146101b957806395d89b41146101b4578063a3760758146101af578063a3ef270b146101aa578063a7ab6961146101a5578063a9059cbb146101a0578063ae76cf2a1461019b578063c303a6a714610196578063c7f71b8a14610191578063d19bd0a71461018c578063dd62ed3e14610187578063ec4d8019146101825763f2fde38b0361000e57610e29565b610df4565b610d6b565b610d08565b610cc3565b610c8e565b610c5b565b610c25565b610bf0565b610bab565b610b76565b610b27565b610af2565b610a9c565b610a69565b610a31565b6109cb565b610996565b61095f565b61084a565b610816565b6107e3565b6107ae565b61070c565b610679565b61061a565b6105a6565b610532565b6104fd565b610411565b6103b6565b6102c9565b60e01c90565b60405190565b600080fd5b600080fd5b600091031261023e57565b61022e565b5190565b60209181520190565b60005b838110610264575050906000910152565b806020918301518185015201610253565b601f801991011690565b61029e6102a76020936102ac9361029581610243565b93848093610247565b95869101610250565b610275565b0190565b6102c6916020820191600081840391015261027f565b90565b346102f9576102d9366004610233565b6102f56102e4610fc3565b6102ec610223565b918291826102b0565b0390f35b610229565b60018060a01b031690565b610312906102fe565b90565b61031e81610309565b0361032557565b600080fd5b9050359061033782610315565b565b90565b61034581610339565b0361034c57565b600080fd5b9050359061035e8261033c565b565b9190604083820312610389578061037d610386926000860161032a565b93602001610351565b90565b61022e565b151590565b61039c9061038e565b9052565b91906103b490600060208501940190610393565b565b346103e7576103e36103d26103cc366004610360565b90610fde565b6103da610223565b918291826103a0565b0390f35b610229565b90602082820312610406576104039160000161032a565b90565b61022e565b60000190565b3461043f576104296104243660046103ec565b6110f8565b610431610223565b8061043b8161040b565b0390f35b610229565b90565b61045b610456610460926102fe565b610444565b6102fe565b90565b61046c90610447565b90565b61047890610463565b90565b906104859061046f565b600052602052604060002090565b1c90565b90565b6104aa9060086104af9302610493565b610497565b90565b906104bd915461049a565b90565b6104d7906104d2600a9160009261047b565b6104b2565b90565b6104e390610339565b9052565b91906104fb906000602085019401906104da565b565b3461052d576105296105186105133660046103ec565b6104c0565b610520610223565b918291826104e7565b0390f35b610229565b3461056257610542366004610233565b61055e61054d61112f565b610555610223565b918291826104e7565b0390f35b610229565b61059d6105a494610593606094989795610589608086019a60008701906104da565b60208501906104da565b60408301906104da565b01906104da565b565b346105da576105b6366004610233565b6105d66105c161119f565b906105cd949294610223565b94859485610567565b0390f35b610229565b9091606082840312610615576106126105fb846000850161032a565b93610609816020860161032a565b93604001610351565b90565b61022e565b3461064b576106476106366106303660046105df565b9161120d565b61063e610223565b918291826103a0565b0390f35b610229565b60ff1690565b61065f90610650565b9052565b919061067790600060208501940190610656565b565b346106a957610689366004610233565b6106a561069461126d565b61069c610223565b91829182610663565b0390f35b610229565b906106b89061046f565b600052602052604060002090565b60ff1690565b6106dc9060086106e19302610493565b6106c6565b90565b906106ef91546106cc565b90565b61070990610704600c916000926106ae565b6106e4565b90565b3461073c576107386107276107223660046103ec565b6106f2565b61072f610223565b918291826103a0565b0390f35b610229565b9060208282031261075b5761075891600001610351565b90565b61022e565b61077461076f61077992610339565b610444565b610339565b90565b9061078690610760565b600052602052604060002090565b6107ab906107a6600b9160009261077c565b6104b2565b90565b346107de576107da6107c96107c4366004610741565b610794565b6107d1610223565b918291826104e7565b0390f35b610229565b34610811576107f3366004610233565b6107fb6116ce565b610803610223565b8061080d8161040b565b0390f35b610229565b346108455761082f610829366004610360565b906117ff565b610837610223565b806108418161040b565b0390f35b610229565b346108785761086261085d366004610741565b6118a9565b61086a610223565b806108748161040b565b0390f35b610229565b91906040838203126108a6578061089a6108a39260008601610351565b93602001610351565b90565b61022e565b5190565b60209181520190565b60200190565b6108c790610339565b9052565b906108d8816020936108be565b0190565b60200190565b906108ff6108f96108f2846108ab565b80936108af565b926108b8565b9060005b8181106109105750505090565b90919261092961092360019286516108cb565b946108dc565b9101919091610903565b909161094e61095c93604084019084820360008601526108e2565b9160208184039101526108e2565b90565b346109915761097861097236600461087d565b90611981565b9061098d610984610223565b92839283610933565b0390f35b610229565b346109c6576109c26109b16109ac3660046103ec565b611a5b565b6109b9610223565b918291826104e7565b0390f35b610229565b346109f9576109db366004610233565b6109e3611aa0565b6109eb610223565b806109f58161040b565b0390f35b610229565b604090610a28610a2f9496959396610a1e606084019860008501906104da565b60208301906104da565b0190610393565b565b34610a6457610a60610a4c610a473660046103ec565b611aaa565b610a57939193610223565b938493846109fe565b0390f35b610229565b34610a9757610a81610a7c366004610741565b611bfc565b610a89610223565b80610a938161040b565b0390f35b610229565b34610aca57610ab4610aaf366004610741565b611d5c565b610abc610223565b80610ac68161040b565b0390f35b610229565b610ad890610309565b9052565b9190610af090600060208501940190610acf565b565b34610b2257610b02366004610233565b610b1e610b0d611d98565b610b15610223565b91829182610adc565b0390f35b610229565b34610b5757610b37366004610233565b610b53610b42611dae565b610b4a610223565b918291826102b0565b0390f35b610229565b610b7390610b6e60099160009261047b565b6104b2565b90565b34610ba657610ba2610b91610b8c3660046103ec565b610b5c565b610b99610223565b918291826104e7565b0390f35b610229565b34610bdb57610bd7610bc6610bc1366004610741565b611dfc565b610bce610223565b918291826104e7565b0390f35b610229565b610bed60076000906104b2565b90565b34610c2057610c00366004610233565b610c1c610c0b610be0565b610c13610223565b918291826104e7565b0390f35b610229565b34610c5657610c52610c41610c3b366004610360565b90611e1c565b610c49610223565b918291826103a0565b0390f35b610229565b34610c8957610c73610c6e3660046103ec565b611eb2565b610c7b610223565b80610c858161040b565b0390f35b610229565b34610cbe57610cba610ca9610ca43660046103ec565b611ede565b610cb1610223565b918291826103a0565b0390f35b610229565b34610cf357610cef610cde610cd9366004610741565b611efd565b610ce6610223565b918291826104e7565b0390f35b610229565b610d0560086000906104b2565b90565b34610d3857610d18366004610233565b610d34610d23610cf8565b610d2b610223565b918291826104e7565b0390f35b610229565b9190604083820312610d665780610d5a610d63926000860161032a565b9360200161032a565b90565b61022e565b34610d9c57610d98610d87610d81366004610d3d565b90611f34565b610d8f610223565b918291826104e7565b0390f35b610229565b7f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea90565b610dce90610463565b90565b610dda90610dc5565b9052565b9190610df290600060208501940190610dd1565b565b34610e2457610e04366004610233565b610e20610e0f610da1565b610e17610223565b91829182610dde565b0390f35b610229565b34610e5757610e41610e3c3660046103ec565b611fca565b610e49610223565b80610e538161040b565b0390f35b610229565b600080fd5b606090565b634e487b7160e01b600052602260045260246000fd5b9060016002830492168015610e9c575b6020831014610e9757565b610e66565b91607f1691610e8c565b60209181520190565b600052602060002090565b9060009291805490610ed5610ece83610e7c565b8094610ea6565b91600181169081600014610f2e5750600114610ef1575b505050565b610efe9192939450610eaf565b916000925b818410610f165750500190388080610eec565b60018160209295939554848601520191019290610f03565b92949550505060ff1916825215156020020190388080610eec565b90610f5391610eba565b90565b634e487b7160e01b600052604160045260246000fd5b90610f7690610275565b810190811067ffffffffffffffff821117610f9057604052565b610f56565b90610fb5610fae92610fa5610223565b93848092610f49565b0383610f6c565b565b610fc090610f95565b90565b610fcb610e61565b50610fd66002610fb7565b90565b600090565b610fe6610fd9565b50610ff9610ff382611ede565b1561038e565b6110165761101191611009611fd5565b919091611fe2565b600190565b61101e610223565b633b09f10560e01b8152806110356004820161040b565b0390fd5b61104a90611045611ff2565b611097565b565b60001b90565b9061105e60ff9161104c565b9181191691161790565b6110719061038e565b90565b90565b9061108c61108761109392611068565b611074565b8254611052565b9055565b6110a081612047565b6110b660016110b1600c84906106ae565b611077565b6110e07f3584ac55fd91fcf5efce973892cccf98c9b1bc944e64135fc1b93132a8e3933e9161046f565b906110e9610223565b806110f38161040b565b0390a2565b61110190611039565b565b600090565b60001c90565b61111a61111f91611108565b610497565b90565b61112c905461110e565b90565b611137611103565b506111426004611122565b90565b90565b61115c61115761116192611145565b610444565b610339565b90565b634e487b7160e01b600052601160045260246000fd5b61118961118f91939293610339565b92610339565b820180921161119a57565b611164565b6111a7611103565b506111b0611103565b506111b9611103565b506111c2611103565b506111cc42611dfc565b906111e1826111db6001611148565b9061117a565b6111f56111f0600b859061077c565b611122565b9161120a611205600b849061077c565b611122565b90565b916112379261121a610fd9565b5061122f611226611fd5565b829084916120cd565b919091612162565b600190565b600090565b90565b61125861125361125d92611241565b610444565b610650565b90565b61126a6012611244565b90565b61127561123c565b5061127e611260565b90565b61128961223d565b611291611385565b6112996122a9565b565b90565b6112b26112ad6112b79261129b565b610444565b610339565b90565b906112c76000199161104c565b9181191691161790565b90565b906112e96112e46112f092610760565b6112d1565b82546112ba565b9055565b61130361130991939293610339565b92610339565b820391821161131457565b611164565b600080fd5b60e01b90565b600091031261132f57565b61022e565b61133c610223565b3d6000823e3d90fd5b61134e90610447565b90565b61135a90611345565b90565b61137161136c6113769261129b565b610444565b6102fe565b90565b6113829061135d565b90565b61138d611fd5565b42906113a361139e600a839061047b565b611122565b91826113b86113b2600061129e565b91610339565b146116ab57806113d06113ca85610339565b91610339565b1115611688576113fb6113f56113f0856113ea6008611122565b9061117a565b610339565b91610339565b1015611665576114156114106009839061047b565b611122565b918261143161142b61142685611a5b565b610339565b91610339565b11611642576114419083906122bd565b61145f61144e600061129e565b61145a600a849061047b565b6112d4565b61147d61146c600061129e565b6114786009849061047b565b6112d4565b6114a58261149f6114906005859061047b565b9161149a83611122565b6112f4565b906112d4565b6114c26114bb836114b66004611122565b6112f4565b60046112d4565b6114eb7f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea610dc5565b63af14052c90803b1561163d5761150f91600091611507610223565b93849261131e565b82528183816115206004820161040b565b03925af180156116385761160b575b5061156c61156461155f7f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea610dc5565b611351565b8284916123db565b8082906115ae61159c7f1a39b9c5044b9f0ff56c5951e30c1ebe24911353aafcceb9250e83a24fe158c49261046f565b926115a5610223565b918291826104e7565b0390a2906115bc6000611379565b90916116066115f46115ee7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9361046f565b9361046f565b936115fd610223565b918291826104e7565b0390a3565b61162b9060003d8111611631575b6116238183610f6c565b810190611324565b3861152f565b503d611619565b611334565b611319565b61164a610223565b631e9acf1760e31b8152806116616004820161040b565b0390fd5b61166d610223565b63dbe67dcd60e01b8152806116846004820161040b565b0390fd5b611690610223565b6360fc88b360e11b8152806116a76004820161040b565b0390fd5b6116b3610223565b630b781b4d60e31b8152806116ca6004820161040b565b0390fd5b6116d6611281565b565b906116ea916116e561223d565b611700565b6116f26122a9565b565b6116fd90610463565b90565b9061170a82612047565b61171381612429565b61173b816117356117266005869061047b565b9161173083611122565b61117a565b906112d4565b6117586117518261174c6004611122565b61117a565b60046112d4565b6117a561178c6117877f00000000000000000000000097a10beebb25e0ebfa55ca0a7d00e37afe957dea610dc5565b611351565b611794611fd5565b61179d306116f4565b908492612499565b6117af6000611379565b9190916117fa6117e86117e27fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9361046f565b9361046f565b936117f1610223565b918291826104e7565b0390a3565b90611809916116d8565b565b61181c90611817611ff2565b61181e565b565b8061183a61183461182f6007611122565b610339565b91610339565b10156118865761184b8160076112d4565b6118817f6f3e5d6a00b186747b385d5be1e4e88c163f2541c4a63e9ecbb55ba29d44670b91611878610223565b918291826104e7565b0390a1565b61188e610223565b633cb2b8d760e11b8152806118a56004820161040b565b0390fd5b6118b29061180b565b565b606090565b906118cc6118c5610223565b9283610f6c565b565b67ffffffffffffffff81116118e65760208091020190565b610f56565b906118fd6118f8836118ce565b6118b9565b918252565b369037565b9061192c611914836118eb565b9260208061192286936118ce565b9201910390611902565b565b600161193a9101610339565b90565b634e487b7160e01b600052603260045260246000fd5b9061195d826108ab565b81101561196e576020809102010190565b61193d565b9061197d90610339565b9052565b6119b56119ae6119a86119c5939594956119996118b4565b506119a26118b4565b50611dfc565b94611dfc565b84906112f4565b6119bf6001611148565b9061117a565b906119cf82611907565b926119d983611907565b916119e4600061129e565b5b806119f86119f287610339565b91610339565b1015611a5457611a4f90611a4a611a38611a33611a1687859061117a565b611a2c81611a278d91889092611953565b611973565b600b61077c565b611122565b611a458791849092611953565b611973565b61192e565b6119e5565b5091925050565b611a72611a7791611a6a611103565b50600561047b565b611122565b90565b611a82611ff2565b611a8a611a8c565b565b611a9e611a996000611379565b612527565b565b611aa8611a7a565b565b90611ab3611103565b50611abc611103565b50611ac5610fd9565b50611aed611ae8611ae0611adb6009869061047b565b611122565b93600a61047b565b611122565b904282611b03611afd600061129e565b91610339565b141580611b44575b9081611b16575b5090565b9050611b3d611b37611b3285611b2c6008611122565b9061117a565b610339565b91610339565b1038611b12565b5080611b58611b5285610339565b91610339565b11611b0b565b611b6f90611b6a611ff2565b611b71565b565b80611b8d611b87611b826008611122565b610339565b91610339565b1115611bd957611b9e8160086112d4565b611bd47f176d9d2c8f84a996862e9cb6ae03eb576184e3fb7621bcbfc6e1828f4b11468091611bcb610223565b918291826104e7565b0390a1565b611be1610223565b6325d4924760e01b815280611bf86004820161040b565b0390fd5b611c0590611b5e565b565b611c1890611c1361223d565b611c46565b611c206122a9565b565b916020611c44929493611c3d604082019660008301906104da565b01906104da565b565b611c4f81612429565b611c57611fd5565b9080611c73611c6d611c6885611a5b565b610339565b91610339565b11611d3957611ca9611c8f611c8a600a859061047b565b611122565b611ca3611c9e6009869061047b565b611122565b906122bd565b611cbd42611cb76007611122565b9061117a565b91611cd383611cce600a849061047b565b6112d4565b611ce882611ce36009849061047b565b6112d4565b611cf3838390612588565b9091611d1f7f31f69201fab7912e3ec9850e3ab705964bf46d9d4276bdcbb6d05e965e5f54019261046f565b92611d34611d2b610223565b92839283611c22565b0390a2565b611d41610223565b631e9acf1760e31b815280611d586004820161040b565b0390fd5b611d6590611c07565b565b600090565b60018060a01b031690565b611d83611d8891611108565b611d6c565b90565b611d959054611d77565b90565b611da0611d67565b50611dab6000611d8b565b90565b611db6610e61565b50611dc16003610fb7565b90565b634e487b7160e01b600052601260045260246000fd5b611de6611dec91610339565b91610339565b908115611df7570490565b611dc4565b611e1990611e08611103565b50611e136008611122565b90611dda565b90565b611e3991611e28610fd9565b50611e31611fd5565b919091612162565b600190565b611e4f90611e4a611ff2565b611e51565b565b611e5a81612047565b611e706000611e6b600c84906106ae565b611077565b611e9a7f124b4488f16f954d5626769cbcab59a035cff89968908f4bbb90c264efcc9b839161046f565b90611ea3610223565b80611ead8161040b565b0390a2565b611ebb90611e3e565b565b611ec9611ece91611108565b6106c6565b90565b611edb9054611ebd565b90565b611ef5611efa91611eed610fd9565b50600c6106ae565b611ed1565b90565b611f14611f1991611f0c611103565b50600b61077c565b611122565b90565b90611f269061046f565b600052602052604060002090565b611f5991611f4f611f5492611f47611103565b506006611f1c565b61047b565b611122565b90565b611f6d90611f68611ff2565b611f6f565b565b80611f8b611f85611f806000611379565b610309565b91610309565b14611f9b57611f9990612527565b565b611fc6611fa86000611379565b611fb0610223565b91829163b20f76e360e01b835260048301610adc565b0390fd5b611fd390611f5c565b565b611fdd611d67565b503390565b91611ff092916001926125b9565b565b611ffa611d98565b61201361200d612008611fd5565b610309565b91610309565b0361201a57565b612043612025611fd5565b61202d610223565b9182916332b2baa360e01b835260048301610adc565b0390fd5b61206261205c6120576000611379565b610309565b91610309565b1461206957565b612071610223565b63d92e233d60e01b8152806120886004820161040b565b0390fd5b6040906120b66120bd94969593966120ac60608401986000850190610acf565b60208301906104da565b01906104da565b565b906120ca9103610339565b90565b9291926120db818390611f34565b90816120f16120eb600019610339565b91610339565b036120fe575b5050509050565b8161211161210b87610339565b91610339565b106121385761212f93946121269193926120bf565b906000926125b9565b803880806120f7565b5061215e84929192612148610223565b938493630c95cf2760e11b85526004850161208c565b0390fd5b918261217f6121796121746000611379565b610309565b91610309565b146121e257816121a061219a6121956000611379565b610309565b91610309565b146121b3576121b1929190916126e8565b565b6121de6121c06000611379565b6121c8610223565b918291639cfea58360e01b835260048301610adc565b0390fd5b61220d6121ef6000611379565b6121f7610223565b9182916313053d9360e21b835260048301610adc565b0390fd5b90565b61222861222361222d92612211565b610444565b610339565b90565b61223a6002612214565b90565b6122476001611122565b61226061225a612255612230565b610339565b91610339565b1461227957612277612270612230565b60016112d4565b565b612281610223565b6306fda65d60e31b8152806122986004820161040b565b0390fd5b6122a66001611148565b90565b6122bb6122b461229c565b60016112d4565b565b806122d16122cb600061129e565b91610339565b14801561235f575b61235b576122e690611dfc565b8161230c6123066123016122fc600b869061077c565b611122565b610339565b91610339565b1161233a576123326123236123389392600b61077c565b9161232d83611122565b6112f4565b906112d4565b565b612359915061235461234c600061129e565b91600b61077c565b6112d4565b565b5050565b508161237461236e600061129e565b91610339565b146122d9565b61238390610463565b90565b63ffffffff1690565b63ffffffff60e01b1690565b6123af6123aa6123b492612386565b61131e565b61238f565b90565b9160206123d99294936123d260408201966000830190610acf565b01906104da565b565b9061242261242793612413600494936123fa63a9059cbb91939161239b565b92612403610223565b96879460208601908152016123b7565b60208201810382520383610f6c565b61285f565b565b61243c612436600061129e565b91610339565b1461244357565b61244b610223565b631f2a200560e01b8152806124626004820161040b565b0390fd5b604090612490612497949695939661248660608401986000850190610acf565b6020830190610acf565b01906104da565b565b6004926124d36124e795936124e293946124ba6323b872dd9294919261239b565b936124c3610223565b9788956020870190815201612466565b60208201810382520383610f6c565b61285f565b565b906124fa60018060a01b039161104c565b9181191691161790565b90565b9061251c6125176125239261046f565b612504565b82546124e9565b9055565b6125316000611d8b565b61253c826000612507565b9061257061256a7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09361046f565b9161046f565b91612579610223565b806125838161040b565b0390a3565b906125b16125a261259b6125b794611dfc565b600b61077c565b916125ac83611122565b61117a565b906112d4565b565b9092816125d76125d16125cc6000611379565b610309565b91610309565b146126ab57836125f86125f26125ed6000611379565b610309565b91610309565b1461267c5761261c8361261761261060068690611f1c565b879061047b565b6112d4565b612626575b505050565b91909161267161265f6126597f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259361046f565b9361046f565b93612668610223565b918291826104e7565b0390a3388080612621565b6126a76126896000611379565b612691610223565b91829163270af7ed60e11b835260048301610adc565b0390fd5b6126d66126b86000611379565b6126c0610223565b9182916322f051b160e21b835260048301610adc565b0390fd5b906126e59101610339565b90565b919091806127076127016126fc6000611379565b610309565b91610309565b146000146127ec5761272c612725836127206004611122565b61117a565b60046112d4565b5b8261274961274361273e6000611379565b610309565b91610309565b146000146127bf5761276e612767836127626004611122565b6120bf565b60046112d4565b5b9190916127ba6127a86127a27fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9361046f565b9361046f565b936127b1610223565b918291826104e7565b0390a3565b6127e7826127e16127d26005879061047b565b916127dc83611122565b6126da565b906112d4565b61276f565b6128006127fb6005839061047b565b611122565b8061281361280d85610339565b91610339565b1061283c576128266128379184906120bf565b6128326005849061047b565b6112d4565b61272d565b612844610223565b631e9acf1760e31b81528061285b6004820161040b565b0390fd5b90600060209161286d611103565b50612876611103565b50828151910182855af115612914573d6000519061289d612897600061129e565b91610339565b146000146128fa57506128af8161237a565b3b6128c36128bd600061129e565b91610339565b145b6128cc5750565b6128d86128f69161237a565b6128e0610223565b918291635274afe760e01b835260048301610adc565b0390fd5b61290d6129076001611148565b91610339565b14156128c5565b6040513d6000823e3d90fdfea2646970667358221220e1a4ec787be00dfee0d5b9ed40777c22695e50c3eb61d50a0bc226c769df91d564736f6c63430008180033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000005ce899aed04c656776148fc3b1adbe59e5f13d5c0000000000000000000000000000000000000000000000000000000000000012566f74652d457363726f7765642053545458000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000067665535454580000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : name_ (string): Vote-Escrowed STTX
Arg [1] : symbol_ (string): veSTTX
Arg [2] : baseContracts_ (address): 0x5Ce899AEd04c656776148fc3b1Adbe59e5f13D5c

-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [2] : 0000000000000000000000005ce899aed04c656776148fc3b1adbe59e5f13d5c
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000012
Arg [4] : 566f74652d457363726f77656420535454580000000000000000000000000000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [6] : 7665535454580000000000000000000000000000000000000000000000000000


[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.