ETH Price: $3,118.33 (-2.38%)
 

Overview

Max Total Supply

424,505,878.52972 JTRSY

Holders

7

Transfers

-
0

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 6 Decimals)

Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

JTRSY is a tokenized T-bill fund, using the Centrifuge protocol for tokenization and fund management.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
Tranche

Compiler Version
v0.8.26+commit.8a97fa7a

Optimization Enabled:
Yes with 500 runs

Other Settings:
cancun EvmVersion
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.26;

import {ERC20} from "src/token/ERC20.sol";
import {IERC20, IERC20Metadata} from "src/interfaces/IERC20.sol";
import {
    IHook,
    HookData,
    SUCCESS_CODE_ID,
    SUCCESS_MESSAGE,
    ERROR_CODE_ID,
    ERROR_MESSAGE
} from "src/interfaces/token/IHook.sol";
import {IERC7575Share, IERC165} from "src/interfaces/IERC7575.sol";
import {ITranche, IERC1404} from "src/interfaces/token/ITranche.sol";
import {MathLib} from "src/libraries/MathLib.sol";

/// @title  Tranche Token
/// @notice Extension of ERC20 + ERC1404 for tranche tokens,
///         integrating an external hook optionally for ERC20 callbacks and ERC1404 checks.
contract Tranche is ERC20, ITranche {
    using MathLib for uint256;

    mapping(address => Balance) private balances;

    /// @inheritdoc ITranche
    address public hook;

    /// @inheritdoc IERC7575Share
    mapping(address asset => address) public vault;

    constructor(uint8 decimals_) ERC20(decimals_) {}

    modifier authOrHook() {
        require(wards[msg.sender] == 1 || msg.sender == hook, "Tranche/not-authorized");
        _;
    }

    // --- Administration ---
    /// @inheritdoc ITranche
    function file(bytes32 what, address data) external authOrHook {
        if (what == "hook") hook = data;
        else revert("Tranche/file-unrecognized-param");
        emit File(what, data);
    }

    /// @inheritdoc ITranche
    function file(bytes32 what, string memory data) public override(ERC20, ITranche) auth {
        super.file(what, data);
    }

    /// @inheritdoc ITranche
    function updateVault(address asset, address vault_) external auth {
        vault[asset] = vault_;
        emit VaultUpdate(asset, vault_);
    }

    // --- ERC20 overrides ---
    function _balanceOf(address user) internal view override returns (uint256) {
        return balances[user].amount;
    }

    function _setBalance(address user, uint256 value) internal override {
        balances[user].amount = value.toUint128();
    }

    /// @inheritdoc ITranche
    function hookDataOf(address user) public view returns (bytes16) {
        return balances[user].hookData;
    }

    /// @inheritdoc ITranche
    function setHookData(address user, bytes16 hookData) public authOrHook {
        balances[user].hookData = hookData;
        emit SetHookData(user, hookData);
    }

    /// @inheritdoc IERC20
    function transfer(address to, uint256 value) public override(ERC20, IERC20) returns (bool success) {
        success = super.transfer(to, value);
        _onTransfer(msg.sender, to, value);
    }

    /// @inheritdoc IERC20
    function transferFrom(address from, address to, uint256 value)
        public
        override(ERC20, IERC20)
        returns (bool success)
    {
        success = super.transferFrom(from, to, value);
        _onTransfer(from, to, value);
    }

    /// @inheritdoc ITranche
    function mint(address to, uint256 value) public override(ERC20, ITranche) {
        super.mint(to, value);
        require(totalSupply <= type(uint128).max, "Tranche/exceeds-max-supply");
        _onTransfer(address(0), to, value);
    }

    /// @inheritdoc ITranche
    function burn(address from, uint256 value) public override(ERC20, ITranche) {
        super.burn(from, value);
        _onTransfer(from, address(0), value);
    }

    function _onTransfer(address from, address to, uint256 value) internal {
        require(
            hook == address(0)
                || IHook(hook).onERC20Transfer(from, to, value, HookData(hookDataOf(from), hookDataOf(to)))
                    == IHook.onERC20Transfer.selector,
            "Tranche/restrictions-failed"
        );
    }

    /// @inheritdoc ITranche
    function authTransferFrom(address sender, address from, address to, uint256 value)
        public
        auth
        returns (bool success)
    {
        success = _transferFrom(sender, from, to, value);
        require(
            hook == address(0)
                || IHook(hook).onERC20AuthTransfer(sender, from, to, value, HookData(hookDataOf(from), hookDataOf(to)))
                    == IHook.onERC20AuthTransfer.selector,
            "Tranche/restrictions-failed"
        );
    }

    // --- ERC1404 implementation ---
    /// @inheritdoc ITranche
    function checkTransferRestriction(address from, address to, uint256 value) public view returns (bool) {
        return detectTransferRestriction(from, to, value) == SUCCESS_CODE_ID;
    }

    /// @inheritdoc IERC1404
    function detectTransferRestriction(address from, address to, uint256 value) public view returns (uint8) {
        if (hook == address(0)) return SUCCESS_CODE_ID;
        return IHook(hook).checkERC20Transfer(from, to, value, HookData(hookDataOf(from), hookDataOf(to)))
            ? SUCCESS_CODE_ID
            : ERROR_CODE_ID;
    }

    /// @inheritdoc IERC1404
    function messageForTransferRestriction(uint8 restrictionCode) external pure returns (string memory) {
        return restrictionCode == SUCCESS_CODE_ID ? SUCCESS_MESSAGE : ERROR_MESSAGE;
    }

    // --- ERC165 support ---
    /// @inheritdoc IERC165
    function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
        return interfaceId == type(IERC7575Share).interfaceId || interfaceId == type(IERC165).interfaceId;
    }
}

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.26;

import {Auth} from "src/Auth.sol";
import {EIP712Lib} from "src/libraries/EIP712Lib.sol";
import {SignatureLib} from "src/libraries/SignatureLib.sol";
import {IERC20, IERC20Metadata, IERC20Permit} from "src/interfaces/IERC20.sol";

/// @title  ERC20
/// @notice Standard ERC-20 implementation, with mint/burn functionality and permit logic.
/// @author Modified from https://github.com/makerdao/xdomain-dss/blob/master/src/Dai.sol
contract ERC20 is Auth, IERC20Metadata, IERC20Permit {
    /// @inheritdoc IERC20Metadata
    string public name;
    /// @inheritdoc IERC20Metadata
    string public symbol;
    /// @inheritdoc IERC20Metadata
    uint8 public immutable decimals;
    /// @inheritdoc IERC20
    uint256 public totalSupply;

    mapping(address => uint256) private balances;

    /// @inheritdoc IERC20
    mapping(address => mapping(address => uint256)) public allowance;
    /// @inheritdoc IERC20Permit
    mapping(address => uint256) public nonces;

    // --- EIP712 ---
    bytes32 private immutable nameHash;
    bytes32 private immutable versionHash;
    uint256 public immutable deploymentChainId;
    bytes32 private immutable _DOMAIN_SEPARATOR;
    bytes32 public constant PERMIT_TYPEHASH =
        keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");

    // --- Events ---
    event File(bytes32 indexed what, string data);

    constructor(uint8 decimals_) Auth(msg.sender) {
        decimals = decimals_;

        nameHash = keccak256(bytes("Centrifuge"));
        versionHash = keccak256(bytes("1"));
        deploymentChainId = block.chainid;
        _DOMAIN_SEPARATOR = EIP712Lib.calculateDomainSeparator(nameHash, versionHash);
    }

    function _balanceOf(address user) internal view virtual returns (uint256) {
        return balances[user];
    }

    /// @inheritdoc IERC20
    function balanceOf(address user) public view virtual returns (uint256) {
        return _balanceOf(user);
    }

    function _setBalance(address user, uint256 value) internal virtual {
        balances[user] = value;
    }

    /// @inheritdoc IERC20Permit
    function DOMAIN_SEPARATOR() public view returns (bytes32) {
        return block.chainid == deploymentChainId
            ? _DOMAIN_SEPARATOR
            : EIP712Lib.calculateDomainSeparator(nameHash, versionHash);
    }

    // --- Administration ---
    function file(bytes32 what, string memory data) public virtual auth {
        if (what == "name") name = data;
        else if (what == "symbol") symbol = data;
        else revert("ERC20/file-unrecognized-param");
        emit File(what, data);
    }

    // --- ERC20 Mutations ---
    /// @inheritdoc IERC20
    function transfer(address to, uint256 value) public virtual returns (bool) {
        require(to != address(0) && to != address(this), "ERC20/invalid-address");
        uint256 balance = balanceOf(msg.sender);
        require(balance >= value, "ERC20/insufficient-balance");

        unchecked {
            _setBalance(msg.sender, _balanceOf(msg.sender) - value);
            // note: we don't need an overflow check here b/c sum of all balances == totalSupply
            _setBalance(to, _balanceOf(to) + value);
        }

        emit Transfer(msg.sender, to, value);

        return true;
    }

    /// @inheritdoc IERC20
    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
        return _transferFrom(msg.sender, from, to, value);
    }

    function _transferFrom(address sender, address from, address to, uint256 value) internal virtual returns (bool) {
        require(to != address(0) && to != address(this), "ERC20/invalid-address");
        uint256 balance = balanceOf(from);
        require(balance >= value, "ERC20/insufficient-balance");

        if (from != sender) {
            uint256 allowed = allowance[from][sender];
            if (allowed != type(uint256).max) {
                require(allowed >= value, "ERC20/insufficient-allowance");
                unchecked {
                    allowance[from][sender] = allowed - value;
                }
            }
        }

        unchecked {
            _setBalance(from, _balanceOf(from) - value);
            // note: we don't need an overflow check here b/c sum of all balances == totalSupply
            _setBalance(to, _balanceOf(to) + value);
        }

        emit Transfer(from, to, value);

        return true;
    }

    /// @inheritdoc IERC20
    function approve(address spender, uint256 value) external returns (bool) {
        allowance[msg.sender][spender] = value;

        emit Approval(msg.sender, spender, value);

        return true;
    }

    // --- Mint/Burn ---
    function mint(address to, uint256 value) public virtual auth {
        require(to != address(0) && to != address(this), "ERC20/invalid-address");
        unchecked {
            // We don't need an overflow check here b/c balances[to] <= totalSupply
            // and there is an overflow check below
            _setBalance(to, _balanceOf(to) + value);
        }
        totalSupply = totalSupply + value;

        emit Transfer(address(0), to, value);
    }

    function burn(address from, uint256 value) public virtual auth {
        uint256 balance = balanceOf(from);
        require(balance >= value, "ERC20/insufficient-balance");

        if (from != msg.sender) {
            uint256 allowed = allowance[from][msg.sender];
            if (allowed != type(uint256).max) {
                require(allowed >= value, "ERC20/insufficient-allowance");

                unchecked {
                    allowance[from][msg.sender] = allowed - value;
                }
            }
        }

        unchecked {
            // We don't need overflow checks b/c require(balance >= value) and balance <= totalSupply
            _setBalance(from, _balanceOf(from) - value);
            totalSupply = totalSupply - value;
        }

        emit Transfer(from, address(0), value);
    }

    // --- Approve by signature ---
    function permit(address owner, address spender, uint256 value, uint256 deadline, bytes memory signature) public {
        require(block.timestamp <= deadline, "ERC20/permit-expired");

        uint256 nonce;
        unchecked {
            nonce = nonces[owner]++;
        }

        bytes32 digest = keccak256(
            abi.encodePacked(
                "\x19\x01",
                DOMAIN_SEPARATOR(),
                keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonce, deadline))
            )
        );

        require(SignatureLib.isValidSignature(owner, digest, signature), "ERC20/invalid-permit");

        allowance[owner][spender] = value;
        emit Approval(owner, spender, value);
    }

    /// @inheritdoc IERC20Permit
    function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
        external
    {
        permit(owner, spender, value, deadline, abi.encodePacked(r, s, v));
    }
}

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.5.0;

/// @title  IERC20
/// @dev    Interface of the ERC20 standard as defined in the EIP.
/// @author Modified from OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
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);
}

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 *
 * ==== Security Considerations
 *
 * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
 * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
 * considered as an intention to spend the allowance in any specific way. The second is that because permits have
 * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
 * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
 * generally recommended is:
 *
 * ```solidity
 * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
 *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
 *     doThing(..., value);
 * }
 *
 * function doThing(..., uint256 value) public {
 *     token.safeTransferFrom(msg.sender, address(this), value);
 *     ...
 * }
 * ```
 *
 * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
 * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
 * {SafeERC20-safeTransferFrom}).
 *
 * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
 * contracts should have entry points that don't rely on permit.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     *
     * CAUTION: See Security Considerations above.
     */
    function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
        external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

interface IERC20Wrapper {
    /**
     * @dev Returns the address of the underlying ERC-20 token that is being wrapped.
     */
    function underlying() external view returns (address);

    /**
     * @dev Allow a user to deposit underlying tokens and mint the corresponding number of wrapped tokens.
     */
    function depositFor(address account, uint256 value) external returns (bool);

    /**
     * @dev Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens.
     */
    function withdrawTo(address account, uint256 value) external returns (bool);
}

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.5.0;

import {IERC165} from "src/interfaces/IERC7575.sol";

struct HookData {
    bytes16 from;
    bytes16 to;
}

uint8 constant SUCCESS_CODE_ID = 0;
string constant SUCCESS_MESSAGE = "transfer-allowed";

uint8 constant ERROR_CODE_ID = 1;
string constant ERROR_MESSAGE = "transfer-blocked";

interface IHook is IERC165 {
    /// @notice Callback on standard ERC20 transfer.
    /// @dev    MUST return bytes4(keccak256("onERC20Transfer(address,address,uint256,(bytes16,bytes16))"))
    ///         if successful
    function onERC20Transfer(address from, address to, uint256 value, HookData calldata hookdata)
        external
        returns (bytes4);

    /// @notice Callback on authorized ERC20 transfer.
    /// @dev    MUST return bytes4(keccak256("onERC20AuthTransfer(address,address,address,uint256,(bytes16,bytes16))"))
    ///         if successful
    function onERC20AuthTransfer(address sender, address from, address to, uint256 value, HookData calldata hookdata)
        external
        returns (bytes4);

    /// @notice Check if given transfer can be performed
    function checkERC20Transfer(address from, address to, uint256 value, HookData calldata hookData)
        external
        view
        returns (bool);

    /// @notice Update a set of restriction for a token
    /// @dev    MAY be user specific, which would be included in the encoded `update` value
    function updateRestriction(address token, bytes memory update) external;
}

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.5.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others.
 */
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[EIP 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);
}

interface IERC7575 is IERC165 {
    event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);
    event Withdraw(
        address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares
    );

    /**
     * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.
     *
     * - MUST be an ERC-20 token contract.
     * - MUST NOT revert.
     */
    function asset() external view returns (address assetTokenAddress);

    /**
     * @dev Returns the address of the share token
     *
     * - MUST be an ERC-20 token contract.
     * - MUST NOT revert.
     */
    function share() external view returns (address shareTokenAddress);

    /**
     * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal
     * scenario where all the conditions are met.
     *
     * - MUST NOT be inclusive of any fees that are charged against assets in the Vault.
     * - MUST NOT show any variations depending on the caller.
     * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
     * - MUST NOT revert.
     *
     * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the
     * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and
     * from.
     */
    function convertToShares(uint256 assets) external view returns (uint256 shares);

    /**
     * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal
     * scenario where all the conditions are met.
     *
     * - MUST NOT be inclusive of any fees that are charged against assets in the Vault.
     * - MUST NOT show any variations depending on the caller.
     * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
     * - MUST NOT revert.
     *
     * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the
     * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and
     * from.
     */
    function convertToAssets(uint256 shares) external view returns (uint256 assets);

    /**
     * @dev Returns the total amount of the underlying asset that is “managed” by Vault.
     *
     * - SHOULD include any compounding that occurs from yield.
     * - MUST be inclusive of any fees that are charged against assets in the Vault.
     * - MUST NOT revert.
     */
    function totalAssets() external view returns (uint256 totalManagedAssets);

    /**
     * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver,
     * through a deposit call.
     *
     * - MUST return a limited value if receiver is subject to some deposit limit.
     * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.
     * - MUST NOT revert.
     */
    function maxDeposit(address receiver) external view returns (uint256 maxAssets);

    /**
     * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given
     * current on-chain conditions.
     *
     * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit
     *   call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called
     *   in the same transaction.
     * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the
     *   deposit would be accepted, regardless if the user has enough tokens approved, etc.
     * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
     * - MUST NOT revert.
     *
     * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in
     * share price or some other type of condition, meaning the depositor will lose assets by depositing.
     */
    function previewDeposit(uint256 assets) external view returns (uint256 shares);

    /**
     * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens.
     *
     * - MUST emit the Deposit event.
     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
     *   deposit execution, and are accounted for during deposit.
     * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not
     *   approving enough underlying tokens to the Vault contract, etc).
     *
     * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
     */
    function deposit(uint256 assets, address receiver) external returns (uint256 shares);

    /**
     * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call.
     * - MUST return a limited value if receiver is subject to some mint limit.
     * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted.
     * - MUST NOT revert.
     */
    function maxMint(address receiver) external view returns (uint256 maxShares);

    /**
     * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given
     * current on-chain conditions.
     *
     * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call
     *   in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the
     *   same transaction.
     * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint
     *   would be accepted, regardless if the user has enough tokens approved, etc.
     * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
     * - MUST NOT revert.
     *
     * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in
     * share price or some other type of condition, meaning the depositor will lose assets by minting.
     */
    function previewMint(uint256 shares) external view returns (uint256 assets);

    /**
     * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens.
     *
     * - MUST emit the Deposit event.
     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint
     *   execution, and are accounted for during mint.
     * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not
     *   approving enough underlying tokens to the Vault contract, etc).
     *
     * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
     */
    function mint(uint256 shares, address receiver) external returns (uint256 assets);

    /**
     * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the
     * Vault, through a withdraw call.
     *
     * - MUST return a limited value if owner is subject to some withdrawal limit or timelock.
     * - MUST NOT revert.
     */
    function maxWithdraw(address owner) external view returns (uint256 maxAssets);

    /**
     * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block,
     * given current on-chain conditions.
     *
     * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw
     *   call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if
     *   called
     *   in the same transaction.
     * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though
     *   the withdrawal would be accepted, regardless if the user has enough shares, etc.
     * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
     * - MUST NOT revert.
     *
     * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in
     * share price or some other type of condition, meaning the depositor will lose assets by depositing.
     */
    function previewWithdraw(uint256 assets) external view returns (uint256 shares);

    /**
     * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver.
     *
     * - MUST emit the Withdraw event.
     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
     *   withdraw execution, and are accounted for during withdraw.
     * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner
     *   not having enough shares, etc).
     *
     * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
     * Those methods should be performed separately.
     */
    function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);

    /**
     * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault,
     * through a redeem call.
     *
     * - MUST return a limited value if owner is subject to some withdrawal limit or timelock.
     * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock.
     * - MUST NOT revert.
     */
    function maxRedeem(address owner) external view returns (uint256 maxShares);

    /**
     * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block,
     * given current on-chain conditions.
     *
     * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call
     *   in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the
     *   same transaction.
     * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the
     *   redemption would be accepted, regardless if the user has enough shares, etc.
     * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
     * - MUST NOT revert.
     *
     * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in
     * share price or some other type of condition, meaning the depositor will lose assets by redeeming.
     */
    function previewRedeem(uint256 shares) external view returns (uint256 assets);

    /**
     * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver.
     *
     * - MUST emit the Withdraw event.
     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
     *   redeem execution, and are accounted for during redeem.
     * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner
     *   not having enough shares, etc).
     *
     * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
     * Those methods should be performed separately.
     */
    function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);
}

interface IERC7575Share is IERC165 {
    event VaultUpdate(address indexed asset, address vault);

    /**
     * @dev Returns the address of the Vault for the given asset.
     *
     * @param asset the ERC-20 token to deposit with into the Vault
     */
    function vault(address asset) external view returns (address);
}

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.5.0;

import {IERC20Metadata} from "src/interfaces/IERC20.sol";
import {IERC7575Share} from "src/interfaces/IERC7575.sol";

interface IERC1404 {
    /// @notice Detects if a transfer will be reverted and if so returns an appropriate reference code
    /// @param from Sending address
    /// @param to Receiving address
    /// @param value Amount of tokens being transferred
    /// @return Code by which to reference message for rejection reasoning
    /// @dev Overwrite with your custom transfer restriction logic
    function detectTransferRestriction(address from, address to, uint256 value) external view returns (uint8);

    /// @notice Returns a human-readable message for a given restriction code
    /// @param restrictionCode Identifier for looking up a message
    /// @return Text showing the restriction's reasoning
    /// @dev Overwrite with your custom message and restrictionCode handling
    function messageForTransferRestriction(uint8 restrictionCode) external view returns (string memory);
}

interface ITranche is IERC20Metadata, IERC7575Share, IERC1404 {
    // --- Events ---
    event File(bytes32 indexed what, address data);
    event SetHookData(address indexed user, bytes16 data);

    struct Balance {
        /// @dev The user balance is limited to uint128. This is safe because the decimals are limited to 18,
        ///      thus the max balance is 2^128-1 / 10**18 = 3.40 * 10**20. This is also enforced on mint.
        uint128 amount;
        /// @dev There are 16 bytes that are used to store hook data (e.g. restrictions for users).
        bytes16 hookData;
    }

    // --- Administration ---
    /// @notice returns the hook that transfers perform callbacks to
    /// @dev    MUST comply to `IHook` interface
    function hook() external view returns (address);

    /// @notice Updates a contract parameter
    /// @param what Accepts a bytes32 representation of 'name', 'symbol'
    function file(bytes32 what, string memory data) external;

    /// @notice Updates a contract parameter
    /// @param what Accepts a bytes32 representation of 'hook'
    function file(bytes32 what, address data) external;

    /// @notice updates the vault for a given `asset`
    function updateVault(address asset, address vault_) external;

    // --- ERC20 overrides ---
    /// @notice returns the 16 byte hook data of the given `user`.
    /// @dev    Stored in the 128 most significant bits of the user balance
    function hookDataOf(address user) external view returns (bytes16);

    /// @notice update the 16 byte hook data of the given `user`
    function setHookData(address user, bytes16 hookData) external;

    /// @notice Function to mint tokens
    function mint(address user, uint256 value) external;

    /// @notice Function to burn tokens
    function burn(address user, uint256 value) external;

    /// @notice Checks if the tokens can be transferred given the input values
    function checkTransferRestriction(address from, address to, uint256 value) external view returns (bool);

    /// @notice Performs an authorized transfer, with `sender` as the given sender.
    /// @dev    Requires allowance if `sender` != `from`
    function authTransferFrom(address sender, address from, address to, uint256 amount) external returns (bool);
}

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.26;

/// @title  Math Lib
/// @dev    Standard math utilities missing in the Solidity language.
/// @author Modified from OpenZeppelin Contracts v4.9.3 (utils/math/Math.sol)
library MathLib {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero

    }

    /// @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
    ///         denominator == 0
    /// @dev    Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
    ///         with further edits by Uniswap Labs also under MIT license.
    // slither-disable-start divide-before-multiply
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1, "Math: mulDiv overflow");

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.
            // Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also
            // works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }
    // slither-disable-end divide-before-multiply

    /// @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /// @notice Safe type conversion from uint256 to uint8.
    function toUint8(uint256 value) internal pure returns (uint8) {
        if (value > type(uint8).max) {
            revert("MathLib/uint8-overflow");
        }
        return uint8(value);
    }

    /// @notice Safe type conversion from uint256 to uint128.
    function toUint128(uint256 _value) internal pure returns (uint128 value) {
        if (_value > type(uint128).max) {
            revert("MathLib/uint128-overflow");
        } else {
            value = uint128(_value);
        }
    }

    /// @notice Returns the smallest of two numbers.
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? b : a;
    }
}

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.26;

import {IAuth} from "src/interfaces/IAuth.sol";

/// @title  Auth
/// @notice Simple authentication pattern
/// @author Based on code from https://github.com/makerdao/dss
abstract contract Auth is IAuth {
    /// @inheritdoc IAuth
    mapping(address => uint256) public wards;

    constructor(address initialWard) {
        wards[initialWard] = 1;
        emit Rely(initialWard);
    }

    /// @dev Check if the msg.sender has permissions
    modifier auth() {
        require(wards[msg.sender] == 1, "Auth/not-authorized");
        _;
    }

    /// @inheritdoc IAuth
    function rely(address user) external auth {
        wards[user] = 1;
        emit Rely(user);
    }

    /// @inheritdoc IAuth
    function deny(address user) external auth {
        wards[user] = 0;
        emit Deny(user);
    }
}

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.26;

/// @title  EIP712 Lib
library EIP712Lib {
    // keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
    bytes32 public constant EIP712_DOMAIN_TYPEHASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;

    function calculateDomainSeparator(bytes32 nameHash, bytes32 versionHash) internal view returns (bytes32) {
        return keccak256(abi.encode(EIP712_DOMAIN_TYPEHASH, nameHash, versionHash, block.chainid, address(this)));
    }
}

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.26;

interface IERC1271 {
    function isValidSignature(bytes32, bytes memory) external view returns (bytes4);
}

/// @title  Signature Lib
library SignatureLib {
    function isValidSignature(address signer, bytes32 digest, bytes memory signature)
        internal
        view
        returns (bool valid)
    {
        require(signer != address(0), "SignatureLib/invalid-signer");

        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            if (signer == ecrecover(digest, v, r, s)) {
                return true;
            }
        }

        if (signer.code.length > 0) {
            (bool success, bytes memory result) =
                signer.staticcall(abi.encodeCall(IERC1271.isValidSignature, (digest, signature)));
            valid =
                (success && result.length == 32 && abi.decode(result, (bytes4)) == IERC1271.isValidSignature.selector);
        }
    }
}

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.5.0;

interface IAuth {
    event Rely(address indexed user);
    event Deny(address indexed user);

    /// @notice Returns whether the target is a ward (has admin access)
    function wards(address target) external view returns (uint256);

    /// @notice Make user a ward (give them admin access)
    function rely(address user) external;

    /// @notice Remove user as a ward (remove admin access)
    function deny(address user) external;
}

Settings
{
  "remappings": [
    "forge-std/=lib/forge-std/src/",
    "@chimera/=lib/chimera/src/",
    "chimera/=lib/chimera/src/",
    "ds-test/=lib/chimera/lib/forge-std/lib/ds-test/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 500
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "cancun",
  "viaIR": false,
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"uint8","name":"decimals_","type":"uint8"}],"stateMutability":"nonpayable","type":"constructor"},{"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":"user","type":"address"}],"name":"Deny","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"what","type":"bytes32"},{"indexed":false,"internalType":"address","name":"data","type":"address"}],"name":"File","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"what","type":"bytes32"},{"indexed":false,"internalType":"string","name":"data","type":"string"}],"name":"File","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"Rely","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"bytes16","name":"data","type":"bytes16"}],"name":"SetHookData","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":"asset","type":"address"},{"indexed":false,"internalType":"address","name":"vault","type":"address"}],"name":"VaultUpdate","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","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":"sender","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"authTransferFrom","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"checkTransferRestriction","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"deny","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deploymentChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"detectTransferRestriction","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"what","type":"bytes32"},{"internalType":"string","name":"data","type":"string"}],"name":"file","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"what","type":"bytes32"},{"internalType":"address","name":"data","type":"address"}],"name":"file","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"hook","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"hookDataOf","outputs":[{"internalType":"bytes16","name":"","type":"bytes16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"restrictionCode","type":"uint8"}],"name":"messageForTransferRestriction","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"rely","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bytes16","name":"hookData","type":"bytes16"}],"name":"setHookData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","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":"success","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":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"vault_","type":"address"}],"name":"updateVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"vault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"wards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

610120604052348015610010575f80fd5b5060405161269338038061269383398101604081905261002f9161015f565b335f81815260208190526040808220600190555183929182917fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a25060ff166080908152604080518082018252600a81526943656e7472696675676560b01b6020918201527fe416b338a274162320c79445ae6604141d1cb08275eb27011b69f002dc094d0560a09081528251808401845260018152603160f81b908301527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660c08181524660e0819052835186517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818801528088019190915260608101939093529582019590955230818301528351808203909201825290930190915281519101206101005250610186565b5f6020828403121561016f575f80fd5b815160ff8116811461017f575f80fd5b9392505050565b60805160a05160c05160e051610100516124c96101ca5f395f61087f01525f818161042901526107b301525f61082e01525f61080901525f6102b901526124c95ff3fe608060405234801561000f575f80fd5b50600436106101e7575f3560e01c80637f5a7c7b11610109578063cd0d00961161009e578063dd62ed3e1161006e578063dd62ed3e14610484578063e8e6dc75146104ae578063f815c03d146104f9578063fa1e713014610521575f80fd5b8063cd0d009614610424578063d4ce14151461044b578063d4e8be831461045e578063d505accf14610471575f80fd5b80639dc29fac116100d95780639dc29fac146103cc5780639fd5a6cf146103df578063a9059cbb146103f2578063bf353dbb14610405575f80fd5b80637f5a7c7b14610373578063887ca2491461039e57806395d89b41146103b15780639c52a7f1146103b9575f80fd5b8063313ce5671161017f5780636a9154aa1161014f5780636a9154aa1461031b57806370a082311461032e5780637ecebe00146103415780637f4ab1dd14610360575f80fd5b8063313ce567146102b45780633644e515146102ed57806340c10f19146102f557806365fae35e14610308575f80fd5b806318160ddd116101ba57806318160ddd146102505780631b451d281461026757806323b872dd1461027a57806330adf81f1461028d575f80fd5b806301ffc9a7146101eb57806306fdde0314610213578063095ea7b314610228578063097ac46e1461023b575b5f80fd5b6101fe6101f9366004611e7f565b610534565b60405190151581526020015b60405180910390f35b61021b61056a565b60405161020a9190611ec8565b6101fe610236366004611ef0565b6105f6565b61024e610249366004611fa3565b610661565b005b61025960035481565b60405190815260200161020a565b61024e610275366004611ffa565b6106c8565b6101fe61028836600461202b565b610790565b6102597f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6102db7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff909116815260200161020a565b6102596107b0565b61024e610303366004611ef0565b6108a1565b61024e610316366004612065565b61090f565b61024e61032936600461207e565b6109a7565b61025961033c366004612065565b610a85565b61025961034f366004612065565b60066020525f908152604090205481565b61021b61036e3660046120cf565b610aab565b600854610386906001600160a01b031681565b6040516001600160a01b03909116815260200161020a565b6101fe6103ac3660046120e8565b610b2a565b61021b610cff565b61024e6103c7366004612065565b610d0c565b61024e6103da366004611ef0565b610da3565b61024e6103ed366004612130565b610db8565b6101fe610400366004611ef0565b610f9d565b610259610413366004612065565b5f6020819052908152604090205481565b6102597f000000000000000000000000000000000000000000000000000000000000000081565b6102db61045936600461202b565b610fb5565b61024e61046c3660046121b0565b6110e1565b61024e61047f3660046121d1565b611212565b610259610492366004611ffa565b600560209081525f928352604080842090915290825290205481565b6104e06104bc366004612065565b6001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6040516001600160801b0319909116815260200161020a565b610386610507366004612065565b60096020525f90815260409020546001600160a01b031681565b6101fe61052f36600461202b565b611281565b5f6001600160e01b0319821663f815c03d60e01b148061056457506001600160e01b031982166301ffc9a760e01b145b92915050565b6001805461057790612237565b80601f01602080910402602001604051908101604052809291908181526020018280546105a390612237565b80156105ee5780601f106105c5576101008083540402835291602001916105ee565b820191905f5260205f20905b8154815290600101906020018083116105d157829003601f168201915b505050505081565b335f8181526005602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106509086815260200190565b60405180910390a350600192915050565b335f908152602081905260409020546001146106ba5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064015b60405180910390fd5b6106c4828261129a565b5050565b335f9081526020819052604090205460011461071c5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b6001600160a01b038281165f81815260096020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff19169486169485179055905192835290917fd8c6b8f6ca4977137bd0c05f8e49099e0bbbefe5ed3010bf828a76dbab95831391015b60405180910390a25050565b5f61079c8484846113a2565b90506107a98484846113af565b9392505050565b5f7f0000000000000000000000000000000000000000000000000000000000000000461461087c5750604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b507f000000000000000000000000000000000000000000000000000000000000000090565b6108ab828261151b565b6003546001600160801b0310156109045760405162461bcd60e51b815260206004820152601a60248201527f5472616e6368652f657863656564732d6d61782d737570706c7900000000000060448201526064016106b1565b6106c45f83836113af565b335f908152602081905260409020546001146109635760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b6001600160a01b0381165f8181526020819052604080822060019055517fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a250565b335f90815260208190526040902054600114806109ce57506008546001600160a01b031633145b610a1a5760405162461bcd60e51b815260206004820152601660248201527f5472616e6368652f6e6f742d617574686f72697a65640000000000000000000060448201526064016106b1565b6001600160a01b0382165f8181526007602090815260409182902080546001600160801b0316600160801b608087901c0217905590516001600160801b0319841681527f8fa29948e0a84e3c738d2e921e65fab6e5a02291fe898fd94d60c3c8ee614c459101610784565b6001600160a01b0381165f908152600760205260408120546001600160801b0316610564565b606060ff821615610af1576040518060400160405280601081526020017f7472616e736665722d626c6f636b656400000000000000000000000000000000815250610564565b505060408051808201909152601081527f7472616e736665722d616c6c6f77656400000000000000000000000000000000602082015290565b335f90815260208190526040812054600114610b7e5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b610b8a8585858561165b565b6008549091506001600160a01b03161580610cab57506008546040805180820190915263078d18cd60e01b916001600160a01b03169063078d18cd90889088908890889080610bf7856001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b0319168152602001610c2e8c6001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b03191690526040516001600160e01b031960e088901b168152610c5f95949392919060040161226f565b6020604051808303815f875af1158015610c7b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c9f91906122ba565b6001600160e01b031916145b610cf75760405162461bcd60e51b815260206004820152601b60248201527f5472616e6368652f7265737472696374696f6e732d6661696c6564000000000060448201526064016106b1565b949350505050565b6002805461057790612237565b335f90815260208190526040902054600114610d605760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b6001600160a01b0381165f81815260208190526040808220829055517f184450df2e323acec0ed3b5c7531b81f9b4cdef7914dfd4c0a4317416bb5251b9190a250565b610dad8282611896565b6106c4825f836113af565b81421115610e085760405162461bcd60e51b815260206004820152601460248201527f45524332302f7065726d69742d6578706972656400000000000000000000000060448201526064016106b1565b6001600160a01b0385165f90815260066020526040812080546001810190915590610e316107b0565b604080517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c960208201526001600160a01b03808b169282019290925290881660608201526080810187905260a0810184905260c0810186905260e00160405160208183030381529060405280519060200120604051602001610eca92919061190160f01b81526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050610eed878285611a75565b610f395760405162461bcd60e51b815260206004820152601460248201527f45524332302f696e76616c69642d7065726d697400000000000000000000000060448201526064016106b1565b6001600160a01b038781165f818152600560209081526040808320948b168084529482529182902089905590518881527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b5f610fa88383611c68565b90506105643384846113af565b6008545f906001600160a01b0316610fce57505f6107a9565b60085f9054906101000a90046001600160a01b03166001600160a01b031663ef59bc9285858560405180604001604052806110278b6001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b031916815260200161105e8a6001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b03191690526040516001600160e01b031960e087901b16815261108e94939291906004016122d5565b602060405180830381865afa1580156110a9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110cd9190612321565b6110d8576001610cf7565b5f949350505050565b335f908152602081905260409020546001148061110857506008546001600160a01b031633145b6111545760405162461bcd60e51b815260206004820152601660248201527f5472616e6368652f6e6f742d617574686f72697a65640000000000000000000060448201526064016106b1565b8163686f6f6b60e01b0361118f576008805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383161790556111d7565b60405162461bcd60e51b815260206004820152601f60248201527f5472616e6368652f66696c652d756e7265636f676e697a65642d706172616d0060448201526064016106b1565b6040516001600160a01b038216815282907f8fef588b5fc1afbf5b2f06c1a435d513f208da2e6704c3d8f0e0ec91167066ba90602001610784565b6112788787878786868960405160200161126493929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b604051602081830303815290604052610db8565b50505050505050565b5f8061128e858585610fb5565b60ff1614949350505050565b335f908152602081905260409020546001146112ee5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b81636e616d6560e01b0361130e576001611308828261238b565b50611372565b81651cde5b589bdb60d21b0361132a576002611308828261238b565b60405162461bcd60e51b815260206004820152601d60248201527f45524332302f66696c652d756e7265636f676e697a65642d706172616d00000060448201526064016106b1565b817fe42e0b9a029dc87ccb1029c632e6359090acd0eb032b2b59c811e3ec70160dc6826040516107849190611ec8565b5f610cf73385858561165b565b6008546001600160a01b031615806114ca575060085460408051808201909152631fb8c88760e11b916001600160a01b031690633f71910e9086908690869080611417856001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b031916815260200161144e8a6001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b03191690526040516001600160e01b031960e087901b16815261147e94939291906004016122d5565b6020604051808303815f875af115801561149a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114be91906122ba565b6001600160e01b031916145b6115165760405162461bcd60e51b815260206004820152601b60248201527f5472616e6368652f7265737472696374696f6e732d6661696c6564000000000060448201526064016106b1565b505050565b335f9081526020819052604090205460011461156f5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b6001600160a01b0382161580159061159057506001600160a01b0382163014155b6115d45760405162461bcd60e51b815260206004820152601560248201527445524332302f696e76616c69642d6164647265737360581b60448201526064016106b1565b6116068282611600856001600160a01b03165f908152600760205260409020546001600160801b031690565b01611dc4565b806003546116149190612446565b6003556040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b5f6001600160a01b0383161580159061167d57506001600160a01b0383163014155b6116c15760405162461bcd60e51b815260206004820152601560248201527445524332302f696e76616c69642d6164647265737360581b60448201526064016106b1565b5f6116cb85610a85565b90508281101561171d5760405162461bcd60e51b815260206004820152601a60248201527f45524332302f696e73756666696369656e742d62616c616e636500000000000060448201526064016106b1565b856001600160a01b0316856001600160a01b0316146117df576001600160a01b038086165f908152600560209081526040808320938a16835292905220545f1981146117dd57838110156117b35760405162461bcd60e51b815260206004820152601c60248201527f45524332302f696e73756666696369656e742d616c6c6f77616e63650000000060448201526064016106b1565b6001600160a01b038087165f908152600560209081526040808320938b1683529290522084820390555b505b611811858461180b886001600160a01b03165f908152600760205260409020546001600160801b031690565b03611dc4565b61183d8484611600876001600160a01b03165f908152600760205260409020546001600160801b031690565b836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161188291815260200190565b60405180910390a350600195945050505050565b335f908152602081905260409020546001146118ea5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b5f6118f483610a85565b9050818110156119465760405162461bcd60e51b815260206004820152601a60248201527f45524332302f696e73756666696369656e742d62616c616e636500000000000060448201526064016106b1565b6001600160a01b03831633146119fb576001600160a01b0383165f9081526005602090815260408083203384529091529020545f1981146119f957828110156119d15760405162461bcd60e51b815260206004820152601c60248201527f45524332302f696e73756666696369656e742d616c6c6f77616e63650000000060448201526064016106b1565b6001600160a01b0384165f908152600560209081526040808320338452909152902083820390555b505b611a27838361180b866001600160a01b03165f908152600760205260409020546001600160801b031690565b6003805483900390556040518281525f906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b5f6001600160a01b038416611acc5760405162461bcd60e51b815260206004820152601b60248201527f5369676e61747572654c69622f696e76616c69642d7369676e6572000000000060448201526064016106b1565b8151604103611b645760208281015160408085015160608087015183515f8082529681018086528a9052951a928501839052840183905260808401819052919260019060a0016020604051602081039080840390855afa158015611b32573d5f803e3d5ffd5b505050602060405103516001600160a01b0316876001600160a01b031603611b6057600193505050506107a9565b5050505b6001600160a01b0384163b156107a9575f80856001600160a01b03168585604051602401611b93929190612465565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16630b135d3f60e11b17905251611bdd919061247d565b5f60405180830381855afa9150503d805f8114611c15576040519150601f19603f3d011682016040523d82523d5f602084013e611c1a565b606091505b5091509150818015611c2d575080516020145b8015611c5e57508051630b135d3f60e11b90611c5290830160209081019084016122ba565b6001600160e01b031916145b9695505050505050565b5f6001600160a01b03831615801590611c8a57506001600160a01b0383163014155b611cce5760405162461bcd60e51b815260206004820152601560248201527445524332302f696e76616c69642d6164647265737360581b60448201526064016106b1565b5f611cd833610a85565b905082811015611d2a5760405162461bcd60e51b815260206004820152601a60248201527f45524332302f696e73756666696369656e742d62616c616e636500000000000060448201526064016106b1565b335f81815260076020526040902054611d4e919085906001600160801b031661180b565b611d7a8484611600876001600160a01b03165f908152600760205260409020546001600160801b031690565b6040518381526001600160a01b0385169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35060019392505050565b611dcd81611e07565b6001600160a01b03929092165f90815260076020526040902080546001600160801b0319166001600160801b039093169290921790915550565b5f6001600160801b03821115611e5f5760405162461bcd60e51b815260206004820152601860248201527f4d6174684c69622f75696e743132382d6f766572666c6f77000000000000000060448201526064016106b1565b50805b919050565b6001600160e01b031981168114611e7c575f80fd5b50565b5f60208284031215611e8f575f80fd5b81356107a981611e67565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f6107a96020830184611e9a565b80356001600160a01b0381168114611e62575f80fd5b5f8060408385031215611f01575f80fd5b611f0a83611eda565b946020939093013593505050565b634e487b7160e01b5f52604160045260245ffd5b5f8067ffffffffffffffff841115611f4657611f46611f18565b50604051601f19601f85018116603f0116810181811067ffffffffffffffff82111715611f7557611f75611f18565b604052838152905080828401851015611f8c575f80fd5b838360208301375f60208583010152509392505050565b5f8060408385031215611fb4575f80fd5b82359150602083013567ffffffffffffffff811115611fd1575f80fd5b8301601f81018513611fe1575f80fd5b611ff085823560208401611f2c565b9150509250929050565b5f806040838503121561200b575f80fd5b61201483611eda565b915061202260208401611eda565b90509250929050565b5f805f6060848603121561203d575f80fd5b61204684611eda565b925061205460208501611eda565b929592945050506040919091013590565b5f60208284031215612075575f80fd5b6107a982611eda565b5f806040838503121561208f575f80fd5b61209883611eda565b915060208301356001600160801b0319811681146120b4575f80fd5b809150509250929050565b803560ff81168114611e62575f80fd5b5f602082840312156120df575f80fd5b6107a9826120bf565b5f805f80608085870312156120fb575f80fd5b61210485611eda565b935061211260208601611eda565b925061212060408601611eda565b9396929550929360600135925050565b5f805f805f60a08688031215612144575f80fd5b61214d86611eda565b945061215b60208701611eda565b93506040860135925060608601359150608086013567ffffffffffffffff811115612184575f80fd5b8601601f81018813612194575f80fd5b6121a388823560208401611f2c565b9150509295509295909350565b5f80604083850312156121c1575f80fd5b8235915061202260208401611eda565b5f805f805f805f60e0888a0312156121e7575f80fd5b6121f088611eda565b96506121fe60208901611eda565b9550604088013594506060880135935061221a608089016120bf565b9699959850939692959460a0840135945060c09093013592915050565b600181811c9082168061224b57607f821691505b60208210810361226957634e487b7160e01b5f52602260045260245ffd5b50919050565b6001600160a01b0386811682528581166020830152841660408201526060810183905260c08101611c5e608083018480516001600160801b0319908116835260209182015116910152565b5f602082840312156122ca575f80fd5b81516107a981611e67565b6001600160a01b038581168252841660208201526040810183905260a08101612318606083018480516001600160801b0319908116835260209182015116910152565b95945050505050565b5f60208284031215612331575f80fd5b815180151581146107a9575f80fd5b601f82111561151657805f5260205f20601f840160051c810160208510156123655750805b601f840160051c820191505b81811015612384575f8155600101612371565b5050505050565b815167ffffffffffffffff8111156123a5576123a5611f18565b6123b9816123b38454612237565b84612340565b6020601f8211600181146123eb575f83156123d45750848201515b5f19600385901b1c1916600184901b178455612384565b5f84815260208120601f198516915b8281101561241a57878501518255602094850194600190920191016123fa565b508482101561243757868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b8082018082111561056457634e487b7160e01b5f52601160045260245ffd5b828152604060208201525f610cf76040830184611e9a565b5f82518060208501845e5f92019182525091905056fea2646970667358221220d96788efce0abae761dd6fa9f185d3e7a99eb9ee0dcc47b2636aa6ead05be32564736f6c634300081a00330000000000000000000000000000000000000000000000000000000000000006

Deployed Bytecode

0x608060405234801561000f575f80fd5b50600436106101e7575f3560e01c80637f5a7c7b11610109578063cd0d00961161009e578063dd62ed3e1161006e578063dd62ed3e14610484578063e8e6dc75146104ae578063f815c03d146104f9578063fa1e713014610521575f80fd5b8063cd0d009614610424578063d4ce14151461044b578063d4e8be831461045e578063d505accf14610471575f80fd5b80639dc29fac116100d95780639dc29fac146103cc5780639fd5a6cf146103df578063a9059cbb146103f2578063bf353dbb14610405575f80fd5b80637f5a7c7b14610373578063887ca2491461039e57806395d89b41146103b15780639c52a7f1146103b9575f80fd5b8063313ce5671161017f5780636a9154aa1161014f5780636a9154aa1461031b57806370a082311461032e5780637ecebe00146103415780637f4ab1dd14610360575f80fd5b8063313ce567146102b45780633644e515146102ed57806340c10f19146102f557806365fae35e14610308575f80fd5b806318160ddd116101ba57806318160ddd146102505780631b451d281461026757806323b872dd1461027a57806330adf81f1461028d575f80fd5b806301ffc9a7146101eb57806306fdde0314610213578063095ea7b314610228578063097ac46e1461023b575b5f80fd5b6101fe6101f9366004611e7f565b610534565b60405190151581526020015b60405180910390f35b61021b61056a565b60405161020a9190611ec8565b6101fe610236366004611ef0565b6105f6565b61024e610249366004611fa3565b610661565b005b61025960035481565b60405190815260200161020a565b61024e610275366004611ffa565b6106c8565b6101fe61028836600461202b565b610790565b6102597f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6102db7f000000000000000000000000000000000000000000000000000000000000000681565b60405160ff909116815260200161020a565b6102596107b0565b61024e610303366004611ef0565b6108a1565b61024e610316366004612065565b61090f565b61024e61032936600461207e565b6109a7565b61025961033c366004612065565b610a85565b61025961034f366004612065565b60066020525f908152604090205481565b61021b61036e3660046120cf565b610aab565b600854610386906001600160a01b031681565b6040516001600160a01b03909116815260200161020a565b6101fe6103ac3660046120e8565b610b2a565b61021b610cff565b61024e6103c7366004612065565b610d0c565b61024e6103da366004611ef0565b610da3565b61024e6103ed366004612130565b610db8565b6101fe610400366004611ef0565b610f9d565b610259610413366004612065565b5f6020819052908152604090205481565b6102597f000000000000000000000000000000000000000000000000000000000000000181565b6102db61045936600461202b565b610fb5565b61024e61046c3660046121b0565b6110e1565b61024e61047f3660046121d1565b611212565b610259610492366004611ffa565b600560209081525f928352604080842090915290825290205481565b6104e06104bc366004612065565b6001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6040516001600160801b0319909116815260200161020a565b610386610507366004612065565b60096020525f90815260409020546001600160a01b031681565b6101fe61052f36600461202b565b611281565b5f6001600160e01b0319821663f815c03d60e01b148061056457506001600160e01b031982166301ffc9a760e01b145b92915050565b6001805461057790612237565b80601f01602080910402602001604051908101604052809291908181526020018280546105a390612237565b80156105ee5780601f106105c5576101008083540402835291602001916105ee565b820191905f5260205f20905b8154815290600101906020018083116105d157829003601f168201915b505050505081565b335f8181526005602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106509086815260200190565b60405180910390a350600192915050565b335f908152602081905260409020546001146106ba5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064015b60405180910390fd5b6106c4828261129a565b5050565b335f9081526020819052604090205460011461071c5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b6001600160a01b038281165f81815260096020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff19169486169485179055905192835290917fd8c6b8f6ca4977137bd0c05f8e49099e0bbbefe5ed3010bf828a76dbab95831391015b60405180910390a25050565b5f61079c8484846113a2565b90506107a98484846113af565b9392505050565b5f7f0000000000000000000000000000000000000000000000000000000000000001461461087c5750604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6020808301919091527fe416b338a274162320c79445ae6604141d1cb08275eb27011b69f002dc094d05828401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b507f8667ee870ef3dcdf8808b2356deae1401df3c16339f40708ab8c44616712591390565b6108ab828261151b565b6003546001600160801b0310156109045760405162461bcd60e51b815260206004820152601a60248201527f5472616e6368652f657863656564732d6d61782d737570706c7900000000000060448201526064016106b1565b6106c45f83836113af565b335f908152602081905260409020546001146109635760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b6001600160a01b0381165f8181526020819052604080822060019055517fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a250565b335f90815260208190526040902054600114806109ce57506008546001600160a01b031633145b610a1a5760405162461bcd60e51b815260206004820152601660248201527f5472616e6368652f6e6f742d617574686f72697a65640000000000000000000060448201526064016106b1565b6001600160a01b0382165f8181526007602090815260409182902080546001600160801b0316600160801b608087901c0217905590516001600160801b0319841681527f8fa29948e0a84e3c738d2e921e65fab6e5a02291fe898fd94d60c3c8ee614c459101610784565b6001600160a01b0381165f908152600760205260408120546001600160801b0316610564565b606060ff821615610af1576040518060400160405280601081526020017f7472616e736665722d626c6f636b656400000000000000000000000000000000815250610564565b505060408051808201909152601081527f7472616e736665722d616c6c6f77656400000000000000000000000000000000602082015290565b335f90815260208190526040812054600114610b7e5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b610b8a8585858561165b565b6008549091506001600160a01b03161580610cab57506008546040805180820190915263078d18cd60e01b916001600160a01b03169063078d18cd90889088908890889080610bf7856001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b0319168152602001610c2e8c6001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b03191690526040516001600160e01b031960e088901b168152610c5f95949392919060040161226f565b6020604051808303815f875af1158015610c7b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c9f91906122ba565b6001600160e01b031916145b610cf75760405162461bcd60e51b815260206004820152601b60248201527f5472616e6368652f7265737472696374696f6e732d6661696c6564000000000060448201526064016106b1565b949350505050565b6002805461057790612237565b335f90815260208190526040902054600114610d605760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b6001600160a01b0381165f81815260208190526040808220829055517f184450df2e323acec0ed3b5c7531b81f9b4cdef7914dfd4c0a4317416bb5251b9190a250565b610dad8282611896565b6106c4825f836113af565b81421115610e085760405162461bcd60e51b815260206004820152601460248201527f45524332302f7065726d69742d6578706972656400000000000000000000000060448201526064016106b1565b6001600160a01b0385165f90815260066020526040812080546001810190915590610e316107b0565b604080517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c960208201526001600160a01b03808b169282019290925290881660608201526080810187905260a0810184905260c0810186905260e00160405160208183030381529060405280519060200120604051602001610eca92919061190160f01b81526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050610eed878285611a75565b610f395760405162461bcd60e51b815260206004820152601460248201527f45524332302f696e76616c69642d7065726d697400000000000000000000000060448201526064016106b1565b6001600160a01b038781165f818152600560209081526040808320948b168084529482529182902089905590518881527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b5f610fa88383611c68565b90506105643384846113af565b6008545f906001600160a01b0316610fce57505f6107a9565b60085f9054906101000a90046001600160a01b03166001600160a01b031663ef59bc9285858560405180604001604052806110278b6001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b031916815260200161105e8a6001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b03191690526040516001600160e01b031960e087901b16815261108e94939291906004016122d5565b602060405180830381865afa1580156110a9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110cd9190612321565b6110d8576001610cf7565b5f949350505050565b335f908152602081905260409020546001148061110857506008546001600160a01b031633145b6111545760405162461bcd60e51b815260206004820152601660248201527f5472616e6368652f6e6f742d617574686f72697a65640000000000000000000060448201526064016106b1565b8163686f6f6b60e01b0361118f576008805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383161790556111d7565b60405162461bcd60e51b815260206004820152601f60248201527f5472616e6368652f66696c652d756e7265636f676e697a65642d706172616d0060448201526064016106b1565b6040516001600160a01b038216815282907f8fef588b5fc1afbf5b2f06c1a435d513f208da2e6704c3d8f0e0ec91167066ba90602001610784565b6112788787878786868960405160200161126493929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b604051602081830303815290604052610db8565b50505050505050565b5f8061128e858585610fb5565b60ff1614949350505050565b335f908152602081905260409020546001146112ee5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b81636e616d6560e01b0361130e576001611308828261238b565b50611372565b81651cde5b589bdb60d21b0361132a576002611308828261238b565b60405162461bcd60e51b815260206004820152601d60248201527f45524332302f66696c652d756e7265636f676e697a65642d706172616d00000060448201526064016106b1565b817fe42e0b9a029dc87ccb1029c632e6359090acd0eb032b2b59c811e3ec70160dc6826040516107849190611ec8565b5f610cf73385858561165b565b6008546001600160a01b031615806114ca575060085460408051808201909152631fb8c88760e11b916001600160a01b031690633f71910e9086908690869080611417856001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b031916815260200161144e8a6001600160a01b03165f90815260076020526040902054600160801b900460801b90565b6001600160801b03191690526040516001600160e01b031960e087901b16815261147e94939291906004016122d5565b6020604051808303815f875af115801561149a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114be91906122ba565b6001600160e01b031916145b6115165760405162461bcd60e51b815260206004820152601b60248201527f5472616e6368652f7265737472696374696f6e732d6661696c6564000000000060448201526064016106b1565b505050565b335f9081526020819052604090205460011461156f5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b6001600160a01b0382161580159061159057506001600160a01b0382163014155b6115d45760405162461bcd60e51b815260206004820152601560248201527445524332302f696e76616c69642d6164647265737360581b60448201526064016106b1565b6116068282611600856001600160a01b03165f908152600760205260409020546001600160801b031690565b01611dc4565b806003546116149190612446565b6003556040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b5f6001600160a01b0383161580159061167d57506001600160a01b0383163014155b6116c15760405162461bcd60e51b815260206004820152601560248201527445524332302f696e76616c69642d6164647265737360581b60448201526064016106b1565b5f6116cb85610a85565b90508281101561171d5760405162461bcd60e51b815260206004820152601a60248201527f45524332302f696e73756666696369656e742d62616c616e636500000000000060448201526064016106b1565b856001600160a01b0316856001600160a01b0316146117df576001600160a01b038086165f908152600560209081526040808320938a16835292905220545f1981146117dd57838110156117b35760405162461bcd60e51b815260206004820152601c60248201527f45524332302f696e73756666696369656e742d616c6c6f77616e63650000000060448201526064016106b1565b6001600160a01b038087165f908152600560209081526040808320938b1683529290522084820390555b505b611811858461180b886001600160a01b03165f908152600760205260409020546001600160801b031690565b03611dc4565b61183d8484611600876001600160a01b03165f908152600760205260409020546001600160801b031690565b836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161188291815260200190565b60405180910390a350600195945050505050565b335f908152602081905260409020546001146118ea5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016106b1565b5f6118f483610a85565b9050818110156119465760405162461bcd60e51b815260206004820152601a60248201527f45524332302f696e73756666696369656e742d62616c616e636500000000000060448201526064016106b1565b6001600160a01b03831633146119fb576001600160a01b0383165f9081526005602090815260408083203384529091529020545f1981146119f957828110156119d15760405162461bcd60e51b815260206004820152601c60248201527f45524332302f696e73756666696369656e742d616c6c6f77616e63650000000060448201526064016106b1565b6001600160a01b0384165f908152600560209081526040808320338452909152902083820390555b505b611a27838361180b866001600160a01b03165f908152600760205260409020546001600160801b031690565b6003805483900390556040518281525f906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b5f6001600160a01b038416611acc5760405162461bcd60e51b815260206004820152601b60248201527f5369676e61747572654c69622f696e76616c69642d7369676e6572000000000060448201526064016106b1565b8151604103611b645760208281015160408085015160608087015183515f8082529681018086528a9052951a928501839052840183905260808401819052919260019060a0016020604051602081039080840390855afa158015611b32573d5f803e3d5ffd5b505050602060405103516001600160a01b0316876001600160a01b031603611b6057600193505050506107a9565b5050505b6001600160a01b0384163b156107a9575f80856001600160a01b03168585604051602401611b93929190612465565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16630b135d3f60e11b17905251611bdd919061247d565b5f60405180830381855afa9150503d805f8114611c15576040519150601f19603f3d011682016040523d82523d5f602084013e611c1a565b606091505b5091509150818015611c2d575080516020145b8015611c5e57508051630b135d3f60e11b90611c5290830160209081019084016122ba565b6001600160e01b031916145b9695505050505050565b5f6001600160a01b03831615801590611c8a57506001600160a01b0383163014155b611cce5760405162461bcd60e51b815260206004820152601560248201527445524332302f696e76616c69642d6164647265737360581b60448201526064016106b1565b5f611cd833610a85565b905082811015611d2a5760405162461bcd60e51b815260206004820152601a60248201527f45524332302f696e73756666696369656e742d62616c616e636500000000000060448201526064016106b1565b335f81815260076020526040902054611d4e919085906001600160801b031661180b565b611d7a8484611600876001600160a01b03165f908152600760205260409020546001600160801b031690565b6040518381526001600160a01b0385169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35060019392505050565b611dcd81611e07565b6001600160a01b03929092165f90815260076020526040902080546001600160801b0319166001600160801b039093169290921790915550565b5f6001600160801b03821115611e5f5760405162461bcd60e51b815260206004820152601860248201527f4d6174684c69622f75696e743132382d6f766572666c6f77000000000000000060448201526064016106b1565b50805b919050565b6001600160e01b031981168114611e7c575f80fd5b50565b5f60208284031215611e8f575f80fd5b81356107a981611e67565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f6107a96020830184611e9a565b80356001600160a01b0381168114611e62575f80fd5b5f8060408385031215611f01575f80fd5b611f0a83611eda565b946020939093013593505050565b634e487b7160e01b5f52604160045260245ffd5b5f8067ffffffffffffffff841115611f4657611f46611f18565b50604051601f19601f85018116603f0116810181811067ffffffffffffffff82111715611f7557611f75611f18565b604052838152905080828401851015611f8c575f80fd5b838360208301375f60208583010152509392505050565b5f8060408385031215611fb4575f80fd5b82359150602083013567ffffffffffffffff811115611fd1575f80fd5b8301601f81018513611fe1575f80fd5b611ff085823560208401611f2c565b9150509250929050565b5f806040838503121561200b575f80fd5b61201483611eda565b915061202260208401611eda565b90509250929050565b5f805f6060848603121561203d575f80fd5b61204684611eda565b925061205460208501611eda565b929592945050506040919091013590565b5f60208284031215612075575f80fd5b6107a982611eda565b5f806040838503121561208f575f80fd5b61209883611eda565b915060208301356001600160801b0319811681146120b4575f80fd5b809150509250929050565b803560ff81168114611e62575f80fd5b5f602082840312156120df575f80fd5b6107a9826120bf565b5f805f80608085870312156120fb575f80fd5b61210485611eda565b935061211260208601611eda565b925061212060408601611eda565b9396929550929360600135925050565b5f805f805f60a08688031215612144575f80fd5b61214d86611eda565b945061215b60208701611eda565b93506040860135925060608601359150608086013567ffffffffffffffff811115612184575f80fd5b8601601f81018813612194575f80fd5b6121a388823560208401611f2c565b9150509295509295909350565b5f80604083850312156121c1575f80fd5b8235915061202260208401611eda565b5f805f805f805f60e0888a0312156121e7575f80fd5b6121f088611eda565b96506121fe60208901611eda565b9550604088013594506060880135935061221a608089016120bf565b9699959850939692959460a0840135945060c09093013592915050565b600181811c9082168061224b57607f821691505b60208210810361226957634e487b7160e01b5f52602260045260245ffd5b50919050565b6001600160a01b0386811682528581166020830152841660408201526060810183905260c08101611c5e608083018480516001600160801b0319908116835260209182015116910152565b5f602082840312156122ca575f80fd5b81516107a981611e67565b6001600160a01b038581168252841660208201526040810183905260a08101612318606083018480516001600160801b0319908116835260209182015116910152565b95945050505050565b5f60208284031215612331575f80fd5b815180151581146107a9575f80fd5b601f82111561151657805f5260205f20601f840160051c810160208510156123655750805b601f840160051c820191505b81811015612384575f8155600101612371565b5050505050565b815167ffffffffffffffff8111156123a5576123a5611f18565b6123b9816123b38454612237565b84612340565b6020601f8211600181146123eb575f83156123d45750848201515b5f19600385901b1c1916600184901b178455612384565b5f84815260208120601f198516915b8281101561241a57878501518255602094850194600190920191016123fa565b508482101561243757868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b8082018082111561056457634e487b7160e01b5f52601160045260245ffd5b828152604060208201525f610cf76040830184611e9a565b5f82518060208501845e5f92019182525091905056fea2646970667358221220d96788efce0abae761dd6fa9f185d3e7a99eb9ee0dcc47b2636aa6ead05be32564736f6c634300081a0033

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

0000000000000000000000000000000000000000000000000000000000000006

-----Decoded View---------------
Arg [0] : decimals_ (uint8): 6

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000006


Loading...
Loading
Loading...
Loading
[ 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.