ETH Price: $3,070.91 (-1.41%)
Gas: 3 Gwei

Token

Staked Yearn Ether (st-yETH)
 

Overview

Max Total Supply

5,472.047156795002709005 st-yETH

Holders

159 ( -0.629%)

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
248.474319303829068219 st-yETH

Value
$0.00
0x20eadfcaf91bd98674ff8fc341d148e1731576a4
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
yETH staking contract

Compiler Version
vyper:0.3.7

Optimization Enabled:
N/A

Other Settings:
GNU AGPLv3 license

Contract Source Code (Vyper language format)

# @version 0.3.7
"""
@title yETH staking contract
@author 0xkorin, Yearn Finance
@license Copyright (c) Yearn Finance, 2023 - all rights reserved
"""

from vyper.interfaces import ERC20
from vyper.interfaces import ERC4626
implements: ERC20
implements: ERC4626

updated: public(uint256)
pending: uint256
streaming: uint256
unlocked: uint256
management: public(address)
pending_management: public(address)

# fees
performance_fee_rate: public(uint256)
treasury: public(address)

# voting
half_time: public(uint256)
previous_packed_weights: HashMap[address, uint256]
packed_weights: HashMap[address, uint256]

# ERC20 state
totalSupply: public(uint256)
balanceOf: public(HashMap[address, uint256])
allowance: public(HashMap[address, HashMap[address, uint256]])

name: public(constant(String[18])) = "Staked Yearn Ether"
symbol: public(constant(String[7])) = "st-yETH"
decimals: public(constant(uint8)) = 18

# ERC4626 state
asset: public(immutable(address))

event Rewards:
    pending: uint256
    streaming: uint256
    unlocked: uint256
    delta: int256

event SetFeeRate:
    fee_rate: uint256

event SetHalfTime:
    half_time: uint256

event PendingManagement:
    management: indexed(address)

event SetManagement:
    management: indexed(address)

event SetTreasury:
    treasury: indexed(address)

# ERC20 events
event Transfer:
    sender: indexed(address)
    receiver: indexed(address)
    value: uint256

event Approval:
    owner: indexed(address)
    spender: indexed(address)
    value: uint256

# ERC4626 events
event Deposit:
    sender: indexed(address)
    owner: indexed(address)
    assets: uint256
    shares: uint256

event Withdraw:
    sender: indexed(address)
    receiver: indexed(address)
    owner: indexed(address)
    assets: uint256
    shares: uint256

FEE_PRECISION: constant(uint256) = 10_000
MINIMUM_INITIAL_DEPOSIT: constant(uint256) = 1_000_000_000_000_000
DAY_LENGTH: constant(uint256) = 24 * 60 * 60
WEEK_LENGTH: constant(uint256) = 7 * DAY_LENGTH
MIN_FEE_RATE: constant(uint256) = 500
MAX_FEE_RATE: constant(uint256) = 2_000
INCREMENT: constant(bool) = True
DECREMENT: constant(bool) = False
WEEK_MASK: constant(uint256) = 2**16 - 1
TIME_MASK: constant(uint256) = 2**56 - 1
TIME_SHIFT: constant(int128) = -16
UPDATED_MASK: constant(uint256) = 2**56 - 1
UPDATED_SHIFT: constant(int128) = -72
SHARES_MASK: constant(uint256) = 2**128 - 1
SHARES_SHIFT: constant(int128) = -128

@external
def __init__(_asset: address):
    """
    @notice Constructor
    @param _asset The underlying asset
    """
    assert _asset != empty(address)
    asset = _asset
    self.updated = block.timestamp
    self.half_time = WEEK_LENGTH
    self.management = msg.sender
    self.treasury = msg.sender
    log Transfer(empty(address), msg.sender, 0)

# ERC20 functions
@external
def transfer(_to: address, _value: uint256) -> bool:
    """
    @notice Transfer to another account
    @param _to Account to transfer to
    @param _value Amount to transfer
    @return True
    """
    assert _to != empty(address) and _to != self
    if _value > 0:
        self._update_account_shares(msg.sender, _value, DECREMENT)
        self._update_account_shares(_to, _value, INCREMENT)
    log Transfer(msg.sender, _to, _value)
    return True

@external
def transferFrom(_from: address, _to: address, _value: uint256) -> bool:
    """
    @notice Transfer from one account to another account
    @param _from Account to transfe from
    @param _to Account to transfer to
    @param _value Amount to transfer
    @return True
    """
    assert _to != empty(address) and _to != self
    self.allowance[_from][msg.sender] -= _value
    if _value > 0:
        self._update_account_shares(_from, _value, DECREMENT)
        self._update_account_shares(_to, _value, INCREMENT)
    log Transfer(_from, _to, _value)
    return True

@external
def approve(_spender: address, _value: uint256) -> bool:
    """
    @notice Approve another account to spend. 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. 
        See https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
    @param _spender Account that is allowed to spend
    @param _value Amount that the spender is allowed to transfer
    @return Flag indicating whether the approval was successful
    """
    assert _spender != empty(address)
    self.allowance[msg.sender][_spender] = _value
    log Approval(msg.sender, _spender, _value)
    return True

@external
def increaseAllowance(_spender: address, _value: uint256) -> bool:
    """
    @notice Increase the allowance of another account to spend. This method mitigates 
        the risk that someone may use both the old and the new allowance by unfortunate 
        transaction ordering.
        See https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
    @param _spender Account that is allowed to spend
    @param _value The amount of tokens to increase the allowance by
    @return True
    """
    assert _spender != empty(address)
    allowance: uint256 = self.allowance[msg.sender][_spender] + _value
    self.allowance[msg.sender][_spender] = allowance
    log Approval(msg.sender, _spender, allowance)
    return True

@external
def decreaseAllowance(_spender: address, _value: uint256) -> bool:
    """
    @notice Decrease the allowance of another account to spend. This method mitigates 
        the risk that someone may use both the old and the new allowance by unfortunate 
        transaction ordering.
        See https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
    @param _spender Account that is allowed to spend
    @param _value The amount of tokens to decrease the allowance by
    @return True
    """
    assert _spender != empty(address)
    allowance: uint256 = self.allowance[msg.sender][_spender]
    if _value > allowance:
        allowance = 0
    else:
        allowance -= _value
    self.allowance[msg.sender][_spender] = allowance
    log Approval(msg.sender, _spender, allowance)
    return True

# ERC4626 functions
@external
@view
def totalAssets() -> uint256:
    """
    @notice Get the total assets in the contract
    @return Total assets in the contract
    """
    total_shares: uint256 = 0
    total_assets: uint256 = 0
    total_shares, total_assets = self._get_totals()
    return total_assets

@external
@view
def convertToShares(_assets: uint256) -> uint256:
    """
    @notice Convert amount of assets to amount of shares
    @param _assets Amount of assets
    @return Amount of shares
    """
    total_shares: uint256 = 0
    total_assets: uint256 = 0
    total_shares, total_assets = self._get_totals()
    if total_shares == 0:
        return _assets
    if total_assets == 0:
        return 0
    return _assets * total_shares / total_assets

@external
@view
def convertToAssets(_shares: uint256) -> uint256:
    """
    @notice Convert amount of shares to amount of assets
    @param _shares Amount of shares
    @return Amount of assets
    """
    total_shares: uint256 = 0
    total_assets: uint256 = 0
    total_shares, total_assets = self._get_totals()
    if total_shares == 0:
        return _shares
    if total_assets == 0:
        return 0
    return _shares * total_assets / total_shares

@external
@view
def maxDeposit(_receiver: address) -> uint256:
    """
    @notice Get the maximum amount of assets an account is allowed to deposit
    @param _receiver Account
    @return Maximum amount the account is allowed to deposit
    """
    return max_value(uint256)

@external
@view
def previewDeposit(_assets: uint256) -> uint256:
    """
    @notice Simulate the effect of a deposit
    @param _assets Amount of assets to deposit
    @return Amount of shares that will be minted
    """
    total_shares: uint256 = 0
    total_assets: uint256 = 0
    total_shares, total_assets = self._get_totals()
    return self._preview_deposit(_assets, total_shares, total_assets)

@external
def deposit(_assets: uint256, _receiver: address = msg.sender) -> uint256:
    """
    @notice Deposit assets
    @param _assets Amount of assets to deposit
    @param _receiver Account that will receive the shares
    @return Amount of shares minted
    """
    assert _assets > 0
    total_shares: uint256 = 0
    total_assets: uint256 = 0
    total_shares, total_assets = self._update_totals()
    shares: uint256 = self._preview_deposit(_assets, total_shares, total_assets)
    assert shares > 0
    self._deposit(_assets, shares, _receiver)
    return shares

@external
@view
def maxMint(_receiver: address) -> uint256:
    """
    @notice Get the maximum amount of shares an account is allowed to mint
    @param _receiver Account
    @return Maximum amount the account is allowed to mint
    """
    return max_value(uint256)

@external
@view
def previewMint(_shares: uint256) -> uint256:
    """
    @notice Simulate the effect of a mint
    @param _shares Amount of shares to mint
    @return Amount of assets that will be taken
    """
    total_shares: uint256 = 0
    total_assets: uint256 = 0
    total_shares, total_assets = self._get_totals()
    return self._preview_mint(_shares, total_shares, total_assets)

@external
def mint(_shares: uint256, _receiver: address = msg.sender) -> uint256:
    """
    @notice Mint shares
    @param _shares Amount of shares to mint
    @param _receiver Account that will receive the shares
    @return Amount of assets taken
    """
    assert _shares > 0
    total_shares: uint256 = 0
    total_assets: uint256 = 0
    total_shares, total_assets = self._update_totals()
    assets: uint256 = self._preview_mint(_shares, total_shares, total_assets)
    assert assets > 0
    self._deposit(assets, _shares, _receiver)
    return assets

@external
@view
def maxWithdraw(_owner: address) -> uint256:
    """
    @notice Get the maximum amount of assets an account is allowed to withdraw
    @param _owner Account
    @return Maximum amount the account is allowed to withdraw
    """
    total_shares: uint256 = 0
    total_assets: uint256 = 0
    total_shares, total_assets = self._get_totals()
    shares: uint256 = self.balanceOf[_owner]
    left: uint256 = total_shares - shares
    if left < MINIMUM_INITIAL_DEPOSIT and left > 0:
        shares = total_shares - MINIMUM_INITIAL_DEPOSIT

    return self._preview_redeem(shares, total_shares, total_assets)

@external
@view
def previewWithdraw(_assets: uint256) -> uint256:
    """
    @notice Simulate the effect of a withdrawal
    @param _assets Amount of assets to withdraw
    @return Amount of shares that will be redeemed
    """
    total_shares: uint256 = 0
    total_assets: uint256 = 0
    total_shares, total_assets = self._get_totals()
    return self._preview_withdraw(_assets, total_shares, total_assets)

@external
def withdraw(_assets: uint256, _receiver: address = msg.sender, _owner: address = msg.sender) -> uint256:
    """
    @notice Withdraw assets
    @param _assets Amount of assets to withdraw
    @param _receiver Account that will receive the assets
    @param _owner Owner of the shares that will be redeemed
    @return Amount of shares redeemed
    """
    assert _assets > 0
    total_shares: uint256 = 0
    total_assets: uint256 = 0
    total_shares, total_assets = self._update_totals()
    shares: uint256 = self._preview_withdraw(_assets, total_shares, total_assets)
    assert shares > 0
    self._withdraw(_assets, shares, _receiver, _owner)
    return shares

@external
@view
def maxRedeem(_owner: address) -> uint256:
    """
    @notice Get the maximum amount of shares an account is allowed to redeem
    @param _owner Account
    @return Maximum amount the account is allowed to redeem
    """
    total_shares: uint256 = 0
    total_assets: uint256 = 0
    total_shares, total_assets = self._get_totals()

    shares: uint256 = self.balanceOf[_owner]
    left: uint256 = total_shares - shares
    if left < MINIMUM_INITIAL_DEPOSIT and left > 0:
        shares = total_shares - MINIMUM_INITIAL_DEPOSIT
    return shares

@external
@view
def previewRedeem(_shares: uint256) -> uint256:
    """
    @notice Simulate the effect of a redemption
    @param _shares Amount of shares to redeem
    @return Amount of assets that will be withdrawn
    """
    total_shares: uint256 = 0
    total_assets: uint256 = 0
    total_shares, total_assets = self._get_totals()
    return self._preview_redeem(_shares, total_shares, total_assets)

@external
def redeem(_shares: uint256, _receiver: address = msg.sender, _owner: address = msg.sender) -> uint256:
    """
    @notice Redeem shares
    @param _shares Amount of shares to redeem
    @param _receiver Account that will receive the assets
    @param _owner Owner of the shares that will be redeemed
    @return Amount of assets withdrawn
    """
    assert _shares > 0
    total_shares: uint256 = 0
    total_assets: uint256 = 0
    total_shares, total_assets = self._update_totals()
    assets: uint256 = self._preview_redeem(_shares, total_shares, total_assets)
    assert assets > 0
    self._withdraw(assets, _shares, _receiver, _owner)
    return assets

# external functions
@external
def update_amounts() -> (uint256, uint256, uint256):
    """
    @notice Update the amount in each bucket
    @return Tuple with pending, streaming and unlocked amounts
    """
    self._update_totals()
    return self.pending, self.streaming, self.unlocked

@external
@view
def get_amounts() -> (uint256, uint256, uint256, uint256, int256):
    """
    @notice Simulate an update to the buckets
    @return Tuple with pending, streaming, unlocked amounts, new fee shares and balance changes since last update
    """
    return self._get_amounts(ERC20(asset).balanceOf(self))

@external
@view
def vote_weight(_account: address) -> uint256:
    """
    @notice Get the voting weight of an account
    @dev Vote weights are always evaluated at the end of last week
    @param _account Account to find get the vote weight for
    @return Vote weight
    """
    current_week: uint256 = block.timestamp / WEEK_LENGTH - 1

    packed_weight: uint256 = self.packed_weights[_account]
    week: uint256 = packed_weight & WEEK_MASK
    if week > current_week:
        packed_weight = self.previous_packed_weights[_account]

    t: uint256 = 0
    updated: uint256 = 0 
    shares: uint256 = 0
    week, t, updated, shares = self._unpack_weight(packed_weight)
    
    if week > 0:
        t += block.timestamp / WEEK_LENGTH * WEEK_LENGTH - updated

    return shares * t / (t + self.half_time)

@external
@view
def known() -> uint256:
    return self.pending + self.streaming + self.unlocked

@external
def rescue(_token: address, _receiver: address):
    assert msg.sender == self.management
    assert _token != asset # dev: cant rescue vault asset
    amount: uint256 = ERC20(_token).balanceOf(self)
    assert ERC20(_token).transfer(_receiver, amount, default_return_value=True)

@external
def set_performance_fee_rate(_fee_rate: uint256):
    """
    @notice Set the performance fee rate
    @param _fee_rate Performance fee rate (in basispoints)
    """
    assert msg.sender == self.management
    assert _fee_rate >= MIN_FEE_RATE and _fee_rate <= MAX_FEE_RATE
    self.performance_fee_rate = _fee_rate
    log SetFeeRate(_fee_rate)

@external
def set_half_time(_half_time: uint256):
    """
    @notice Set the time to reach half the voting weights
    @param _half_time Time to reach half voting weight (in seconds)
    """
    assert msg.sender == self.management
    assert _half_time > 0
    self.half_time = _half_time
    log SetHalfTime(_half_time)

@external
def set_management(_management: address):
    """
    @notice Set the pending management address. Needs to be accepted
    by that account separately to transfer management over
    @param _management New pending management address
    """
    assert msg.sender == self.management
    self.pending_management = _management
    log PendingManagement(_management)

@external
def accept_management():
    """
    @notice Accept management role. Can only be called by account 
    previously marked as pending management by current management
    """
    assert msg.sender == self.pending_management
    self.pending_management = empty(address)
    self.management = msg.sender
    log SetManagement(msg.sender)

@external
def set_treasury(_treasury: address):
    """
    @notice Set the performance fee beneficiary
    @param _treasury The new treasury address
    """
    assert msg.sender == self.management or msg.sender == self.treasury
    assert _treasury != empty(address)
    self.treasury = _treasury
    log SetTreasury(_treasury)

@internal
@view
def _preview_deposit(_assets: uint256, _total_shares: uint256, _total_assets: uint256) -> uint256:
    """
    @notice Calculate amount of shares that will be minted on deposit of a specific amount of assets
    @param _assets Amount of assets to deposit
    @param _total_shares Amount of vault shares prior to deposit
    @param _total_assets Amount of assets in vault prior to deposit
    @return Amount of shares to be minted
    """
    if _total_shares == 0:
        assert _assets >= MINIMUM_INITIAL_DEPOSIT # dev: minimum initial deposit size
        return _assets
    if _total_assets == 0:
        return 0
    return _assets * _total_shares / _total_assets

@internal
@view
def _preview_mint(_shares: uint256, _total_shares: uint256, _total_assets: uint256) -> uint256:
    """
    @notice Calculate amount of assets deposited to mint a specific amount of shares
    @param _assets Amount of shares to mint
    @param _total_shares Amount of vault shares prior to deposit
    @param _total_assets Amount of assets in vault prior to deposit
    @return Amount of assets to deposit
    """
    if _total_shares == 0:
        assert _shares >= MINIMUM_INITIAL_DEPOSIT # dev: minimum initial deposit size
        return _shares
    if _total_assets == 0:
        return 0
    return _shares * _total_assets / _total_shares

@internal
def _deposit(_assets: uint256, _shares: uint256, _receiver: address):
    """
    @notice Deposit assets and mint shares
    @param _assets Amount of assets deposited
    @param _shares Amount of shares minted
    @param _receiver Receiver of minted shares
    """
    self.unlocked += _assets
    self.totalSupply += _shares
    self._update_account_shares(_receiver, _shares, INCREMENT)
    
    assert ERC20(asset).transferFrom(msg.sender, self, _assets, default_return_value=True)
    log Deposit(msg.sender, _receiver, _assets, _shares)
    log Transfer(empty(address), _receiver, _shares)

@internal
@view
def _preview_withdraw(_assets: uint256, _total_shares: uint256, _total_assets: uint256) -> uint256:
    """
    @notice Calculate amount of shares that will be burned on withdrawal of a specific amount of assets
    @param _assets Amount of assets to withdraw
    @param _total_shares Amount of vault shares prior to withdrawal
    @param _total_assets Amount of assets in vault prior to withdrawal
    @return Amount of shares to be burned
    """
    if _total_assets == 0:
        return 0
    return _assets * _total_shares / _total_assets

@internal
@view
def _preview_redeem(_shares: uint256, _total_shares: uint256, _total_assets: uint256) -> uint256:
    """
    @notice Calculate amount of assets withdrawn to burn a specific amount of shares
    @param _assets Amount of shares to burn
    @param _total_shares Amount of vault shares prior to withdrawal
    @param _total_assets Amount of assets in vault prior to withdrawal
    @return Amount of assets to withdraw
    """
    if _total_shares == 0:
        return 0
    return _shares * _total_assets / _total_shares

@internal
def _withdraw(_assets: uint256, _shares: uint256, _receiver: address, _owner: address):
    """
    @notice Withdraw assets and burn shares
    @param _assets Amount of assets withdrawn
    @param _shares Amount of shares burned
    @param _receiver Receiver of withdrawn assets
    @param _owner Account to burn shares from
    """
    if _owner != msg.sender:
        self.allowance[_owner][msg.sender] -= _shares # dev: allowance
    
    self.unlocked -= _assets
    total_shares: uint256 = self.totalSupply - _shares
    self.totalSupply = total_shares
    self._update_account_shares(_owner, _shares, DECREMENT)

    if total_shares < MINIMUM_INITIAL_DEPOSIT:
        assert total_shares == 0

    assert ERC20(asset).transfer(_receiver, _assets, default_return_value=True)
    log Transfer(_owner, empty(address), _shares)
    log Withdraw(msg.sender, _receiver, _owner, _assets, _shares)

@internal
@view
def _get_totals() -> (uint256, uint256):
    """
    @notice Simulate an update to the buckets and return total number of shares and assets
    @return Tuple with total number of shares and total number of assets
    """
    pending: uint256 = 0
    streaming: uint256 = 0
    unlocked: uint256 = 0
    new_fee_shares: uint256 = 0
    delta: int256 = 0
    pending, streaming, unlocked, new_fee_shares, delta = self._get_amounts(ERC20(asset).balanceOf(self))
    return self.totalSupply + new_fee_shares, unlocked

@internal
def _update_totals() -> (uint256, uint256):
    """
    @notice Update the buckets and return total number of shares and assets
    @return Tuple with total number of shares and total number of assets
    """
    current: uint256 = ERC20(asset).balanceOf(self)
    pending: uint256 = 0
    streaming: uint256 = 0
    unlocked: uint256 = 0
    new_fee_shares: uint256 = 0
    delta: int256 = 0
    pending, streaming, unlocked, new_fee_shares, delta = self._get_amounts(current)

    if delta != 0:
        log Rewards(pending, streaming, unlocked, delta)

    self.updated = block.timestamp
    self.pending = pending
    self.streaming = streaming
    self.unlocked = unlocked

    total_shares: uint256 = self.totalSupply
    if new_fee_shares > 0:
        total_shares += new_fee_shares
        self.totalSupply = total_shares
        treasury: address = self.treasury
        self._update_account_shares(treasury, new_fee_shares, INCREMENT)
        log Transfer(empty(address), treasury, new_fee_shares)

    return total_shares, unlocked

@internal
@view
def _get_amounts(_current: uint256) -> (uint256, uint256, uint256, uint256, int256):
    """
    @notice Calculate latest bucket amounts
    @param _current Asset token balance of contract
    @return Tuple with pending, streaming, unlocked amounts, new fee shares and balance changes since last update
    @dev
        New assets not from deposits during a week are added to the pending bucket.
        Streaming bucket gradually streams into the unlocked bucket during the week.
        At the end of the week, the pending bucket becomes the streaming bucket and a new pending bucket is created.
        Slashings are taken from the pending, streaming and unlocked bucket, in that order.
        User deposits and withdrawals only ever affect the unlocked bucket
    """
    updated: uint256 = self.updated
    if updated == block.timestamp:
        return self.pending, self.streaming, self.unlocked, 0, 0

    new_fee: uint256 = 0
    current: uint256 = _current
    pending: uint256 = self.pending
    streaming: uint256 = self.streaming
    unlocked: uint256 = self.unlocked
    last: uint256 = pending + streaming + unlocked

    delta: int256 = 0
    weeks: uint256 = block.timestamp / WEEK_LENGTH - updated / WEEK_LENGTH
    if weeks > 0:
        if weeks == 1:
            # new week
            unlocked += streaming
            streaming = pending
            pending = 0
        else:
            # week number has changed by at least 2 - function hasnt been called in at least a week
            span: uint256 = block.timestamp - updated
            unlocked += streaming + pending
            if current > last:
                # net rewards generated, distribute over buckets
                rewards: uint256 = current - last
                fee: uint256 = rewards * self.performance_fee_rate / FEE_PRECISION
                rewards -= fee
                new_fee += fee

                delta = convert(rewards, int256)
                last = current

                # streaming bucket: 7 days
                streaming = rewards * WEEK_LENGTH / span
                span -= WEEK_LENGTH
                rewards -= streaming

                # pending bucket: time since new week
                pending = rewards * (block.timestamp % WEEK_LENGTH) / span
                rewards -= pending

                # unlocked bucket: rest
                unlocked += rewards
            else:
                # net penalty - deal with it below
                streaming = 0
                pending = 0

        # set to beginning of the week
        updated = block.timestamp / WEEK_LENGTH * WEEK_LENGTH

    # time between last update and end of week
    duration: uint256 = WEEK_LENGTH - (updated % WEEK_LENGTH)
    # time that has passed since last update
    span: uint256 = block.timestamp - updated

    # unlock funds
    streamed: uint256 = streaming * span / duration
    streaming -= streamed
    unlocked += streamed

    if current >= last:
        # rewards
        rewards: uint256 = current - last
        fee: uint256 = rewards * self.performance_fee_rate / FEE_PRECISION
        rewards -= fee
        new_fee += fee
        if weeks == 1 and block.timestamp % WEEK_LENGTH <= DAY_LENGTH:
            # if first update in new week is in first day, add to streaming
            streaming += rewards
        else:
            pending += rewards
        delta += convert(rewards, int256)
    else:
        # penalty
        shortage: uint256 = last - current
        delta -= convert(shortage, int256)
        if pending >= shortage:
            # there are enough pending assets to cover the penalty
            pending -= shortage
        else:
            shortage -= pending
            pending = 0
            if streaming >= shortage:
                # there are enough streaming assets to cover the penalty
                streaming -= shortage
            else:
                # as a last resort, take from unlocked funds
                shortage -= streaming
                streaming = 0
                unlocked -= shortage

    new_fee_shares: uint256 = 0
    if new_fee > 0:
        if unlocked == 0:
            new_fee_shares = new_fee
        else:
            new_fee_shares = new_fee * self.totalSupply / unlocked

        unlocked += new_fee

    return pending, streaming, unlocked, new_fee_shares, delta

@internal
def _update_account_shares(_account: address, _change: uint256, _add: bool):
    """
    @notice Increase or decrease user shares and vote weight accordingly
    @param _account Account to update shares and vote weight for
    @param _change Amount of shares to add or remove
    @param _add True if shares are added, False if removed
    @dev 
        Vote weight is the same immediately before and immediately after a deposit.
        A withdrawal reduces the vote weight proportionally
    """
    
    prev_shares: uint256 = self.balanceOf[_account]
    shares: uint256 = prev_shares
    if _add == INCREMENT:
        shares += _change
    else:
        shares -= _change
    self.balanceOf[_account] = shares

    current_week: uint256 = block.timestamp / WEEK_LENGTH

    week: uint256 = 0
    t: uint256 = 0
    updated: uint256 = 0 
    last_shares: uint256 = 0
    week, t, updated, last_shares = self._unpack_weight(self.packed_weights[_account])
    if week > 0 and current_week > week:
        self.previous_packed_weights[_account] = self.packed_weights[_account]

    if shares == 0:
        t = 0
        last_shares = 0

    if last_shares > 0:
        t += block.timestamp - updated
        if _add == INCREMENT:
            # amount has increased, calculate effective time that results in same weight
            half_time: uint256 = self.half_time
            t = prev_shares * t * half_time / (shares * (t + half_time) - prev_shares * t)

    self.packed_weights[_account] = self._pack_weight(current_week, t, block.timestamp, shares)

@internal
@pure
def _pack_weight(_week: uint256, _t: uint256, _updated: uint256, _shares: uint256) -> uint256:
    """
    @notice Pack voting weight parameters into a single word
    @param _week Week number
    @param _t Time staked
    @param _updated Time last updated
    @param _shares Amount of shares
    @return Packed vote weight
    """
    assert _week <= WEEK_MASK and _t <= TIME_MASK and _updated <= UPDATED_MASK and _shares <= SHARES_MASK
    return _week | shift(_t, -TIME_SHIFT) | shift(_updated, -UPDATED_SHIFT) | shift(_shares, -SHARES_SHIFT)

@internal
@pure
def _unpack_weight(_packed: uint256) -> (uint256, uint256, uint256, uint256):
    """
    @notice Unpack voting weight into its parameters
    @param _packed Packed voting weight
    @return Tuple of week number, time staked, time last updated,amount of shares
    """
    return _packed & WEEK_MASK, shift(_packed, TIME_SHIFT) & TIME_MASK, shift(_packed, UPDATED_SHIFT) & UPDATED_MASK, shift(_packed, SHARES_SHIFT)

Contract Security Audit

Contract ABI

[{"name":"Rewards","inputs":[{"name":"pending","type":"uint256","indexed":false},{"name":"streaming","type":"uint256","indexed":false},{"name":"unlocked","type":"uint256","indexed":false},{"name":"delta","type":"int256","indexed":false}],"anonymous":false,"type":"event"},{"name":"SetFeeRate","inputs":[{"name":"fee_rate","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"SetHalfTime","inputs":[{"name":"half_time","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"PendingManagement","inputs":[{"name":"management","type":"address","indexed":true}],"anonymous":false,"type":"event"},{"name":"SetManagement","inputs":[{"name":"management","type":"address","indexed":true}],"anonymous":false,"type":"event"},{"name":"SetTreasury","inputs":[{"name":"treasury","type":"address","indexed":true}],"anonymous":false,"type":"event"},{"name":"Transfer","inputs":[{"name":"sender","type":"address","indexed":true},{"name":"receiver","type":"address","indexed":true},{"name":"value","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"Approval","inputs":[{"name":"owner","type":"address","indexed":true},{"name":"spender","type":"address","indexed":true},{"name":"value","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"Deposit","inputs":[{"name":"sender","type":"address","indexed":true},{"name":"owner","type":"address","indexed":true},{"name":"assets","type":"uint256","indexed":false},{"name":"shares","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"Withdraw","inputs":[{"name":"sender","type":"address","indexed":true},{"name":"receiver","type":"address","indexed":true},{"name":"owner","type":"address","indexed":true},{"name":"assets","type":"uint256","indexed":false},{"name":"shares","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"stateMutability":"nonpayable","type":"constructor","inputs":[{"name":"_asset","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"transfer","inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"nonpayable","type":"function","name":"transferFrom","inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"nonpayable","type":"function","name":"approve","inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"nonpayable","type":"function","name":"increaseAllowance","inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"nonpayable","type":"function","name":"decreaseAllowance","inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"view","type":"function","name":"totalAssets","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"convertToShares","inputs":[{"name":"_assets","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"convertToAssets","inputs":[{"name":"_shares","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"maxDeposit","inputs":[{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"previewDeposit","inputs":[{"name":"_assets","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"deposit","inputs":[{"name":"_assets","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"deposit","inputs":[{"name":"_assets","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"maxMint","inputs":[{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"previewMint","inputs":[{"name":"_shares","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"mint","inputs":[{"name":"_shares","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"mint","inputs":[{"name":"_shares","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"maxWithdraw","inputs":[{"name":"_owner","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"previewWithdraw","inputs":[{"name":"_assets","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"withdraw","inputs":[{"name":"_assets","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"withdraw","inputs":[{"name":"_assets","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"withdraw","inputs":[{"name":"_assets","type":"uint256"},{"name":"_receiver","type":"address"},{"name":"_owner","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"maxRedeem","inputs":[{"name":"_owner","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"previewRedeem","inputs":[{"name":"_shares","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"redeem","inputs":[{"name":"_shares","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"redeem","inputs":[{"name":"_shares","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"redeem","inputs":[{"name":"_shares","type":"uint256"},{"name":"_receiver","type":"address"},{"name":"_owner","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"update_amounts","inputs":[],"outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"get_amounts","inputs":[],"outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"int256"}]},{"stateMutability":"view","type":"function","name":"vote_weight","inputs":[{"name":"_account","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"known","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"rescue","inputs":[{"name":"_token","type":"address"},{"name":"_receiver","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"set_performance_fee_rate","inputs":[{"name":"_fee_rate","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"set_half_time","inputs":[{"name":"_half_time","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"set_management","inputs":[{"name":"_management","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"accept_management","inputs":[],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"set_treasury","inputs":[{"name":"_treasury","type":"address"}],"outputs":[]},{"stateMutability":"view","type":"function","name":"updated","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"management","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"pending_management","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"performance_fee_rate","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"treasury","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"half_time","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"totalSupply","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"balanceOf","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"allowance","inputs":[{"name":"arg0","type":"address"},{"name":"arg1","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"name","inputs":[],"outputs":[{"name":"","type":"string"}]},{"stateMutability":"view","type":"function","name":"symbol","inputs":[],"outputs":[{"name":"","type":"string"}]},{"stateMutability":"view","type":"function","name":"decimals","inputs":[],"outputs":[{"name":"","type":"uint8"}]},{"stateMutability":"view","type":"function","name":"asset","inputs":[],"outputs":[{"name":"","type":"address"}]}]

602061246a6000396000518060a01c61246557604052346124655760405115612465576040516123e8524260005562093a8060085533600455336007553360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600060605260206060a36123e861007c61000039612408610000f36003361161000c57611487565b60003560e01c346123d65763a9059cbb81186100d157604436106123d6576004358060a01c6123d65761028052610280511561004e5730610280511415610051565b60005b156123d65760243515610091573360c05260243560e05260006101005261007661155a565b6102805160c05260243560e05260016101005261009161155a565b61028051337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6024356102a05260206102a0a360016102a05260206102a0f35b6323b872dd81186101d657606436106123d6576004358060a01c6123d657610280526024358060a01c6123d6576102a0526102a0511561011757306102a051141561011a565b60005b156123d657600d61028051602052600052604060002080336020526000526040600020905080546044358082038281116123d6579050905081555060443515610193576102805160c05260443560e05260006101005261017861155a565b6102a05160c05260443560e05260016101005261019361155a565b6102a051610280517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6044356102c05260206102c0a360016102c05260206102c0f35b63095ea7b3811861025d57604436106123d6576004358060a01c6123d657604052604051156123d657602435600d336020526000526040600020806040516020526000526040600020905055604051337f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560243560605260206060a3600160605260206060f35b6339509351811861031857604436106123d6576004358060a01c6123d657604052604051156123d657600d3360205260005260406000208060405160205260005260406000209050546024358082018281106123d65790509050606052606051600d336020526000526040600020806040516020526000526040600020905055604051337f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560605160805260206080a3600160805260206080f35b63a457c2d781186103ef57604436106123d6576004358060a01c6123d657604052604051156123d657600d3360205260005260406000208060405160205260005260406000209050546060526060516024351161038b576060516024358082038281116123d65790509050606052610391565b60006060525b606051600d336020526000526040600020806040516020526000526040600020905055604051337f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560605160805260206080a3600160805260206080f35b6301e1d114811861042e57600436106123d6576040366103a0376104146103e0611d6f565b6103e080516103a05260208101516103c0525060206103c0f35b63c6e6f59281186104cf57602436106123d6576040366103a0376104536103e0611d6f565b6103e080516103a05260208101516103c052506103a05161047f576004356103e05260206103e06104cd565b6103c0516104975760006103e05260206103e06104cd565b6004356103a0518082028115838383041417156123d657905090506103c05180156123d657808204905090506103e05260206103e05bf35b6307a2d13a811861057057602436106123d6576040366103a0376104f46103e0611d6f565b6103e080516103a05260208101516103c052506103a051610520576004356103e05260206103e061056e565b6103c0516105385760006103e05260206103e061056e565b6004356103c0518082028115838383041417156123d657905090506103a05180156123d657808204905090506103e05260206103e05bf35b63402d267d81186105bb57602436106123d6576004358060a01c6123d6576040527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60605260206060f35b63ef8b30f7811861061957602436106123d6576040366103a0376105e06103e0611d6f565b6103e080516103a05260208101516103c0525060206004356040526103a0516060526103c0516080526106146103e0611e18565b6103e0f35b63b6b55f25811861063657602436106123d657336103e052610659565b636e553f6581186106dc57604436106123d6576024358060a01c6123d6576103e0525b600435156123d65760403661040037610673610440611e7b565b6104408051610400526020810151610420525060043560405261040051606052610420516080526106a5610460611e18565b610460516104405261044051156123d65760043561028052610440516102a0526103e0516102c0526106d561200f565b6020610440f35b63c63d75b6811861072757602436106123d6576004358060a01c6123d6576040527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60605260206060f35b63b3d7f6b9811861078557602436106123d6576040366103a03761074c6103e0611d6f565b6103e080516103a05260208101516103c0525060206004356040526103a0516060526103c0516080526107806103e061214d565b6103e0f35b63a0712d6881186107a257602436106123d657336103e0526107c5565b6394bf804d811861084857604436106123d6576024358060a01c6123d6576103e0525b600435156123d657604036610400376107df610440611e7b565b61044080516104005260208101516104205250600435604052610400516060526104205160805261081161046061214d565b610460516104405261044051156123d65761044051610280526004356102a0526103e0516102c05261084161200f565b6020610440f35b63ce96cb77811861092757602436106123d6576004358060a01c6123d6576103a0526040366103c03761087c610400611d6f565b61040080516103c05260208101516103e05250600c6103a051602052600052604060002054610400526103c051610400518082038281116123d657905090506104205266038d7ea4c67fff6104205111156108d85760006108df565b6104205115155b15610900576103c05166038d7ea4c6800081038181116123d6579050610400525b6020610400516040526103c0516060526103e0516080526109226104406121b0565b610440f35b630a28a477811861098557602436106123d6576040366103a03761094c6103e0611d6f565b6103e080516103a05260208101516103c0525060206004356040526103a0516060526103c0516080526109806103e06121f1565b6103e0f35b632e1a7d4d81186109a757602436106123d657336103e0523361040052610a04565b62f714ce81186109d257604436106123d6576024358060a01c6123d6576103e0523361040052610a04565b63b460af948118610a8f57606436106123d6576024358060a01c6123d6576103e0526044358060a01c6123d657610400525b600435156123d65760403661042037610a1e610460611e7b565b610460805161042052602081015161044052506004356040526104205160605261044051608052610a506104806121f1565b610480516104605261046051156123d65760043561028052610460516102a0526103e0516102c052610400516102e052610a88612232565b6020610460f35b63d905777e8118610b4e57602436106123d6576004358060a01c6123d6576103a0526040366103c037610ac3610400611d6f565b61040080516103c05260208101516103e05250600c6103a051602052600052604060002054610400526103c051610400518082038281116123d657905090506104205266038d7ea4c67fff610420511115610b1f576000610b26565b6104205115155b15610b47576103c05166038d7ea4c6800081038181116123d6579050610400525b6020610400f35b634cdad5068118610bac57602436106123d6576040366103a037610b736103e0611d6f565b6103e080516103a05260208101516103c0525060206004356040526103a0516060526103c051608052610ba76103e06121b0565b6103e0f35b63db006a758118610bce57602436106123d657336103e0523361040052610c2c565b637bde82f28118610bfa57604436106123d6576024358060a01c6123d6576103e0523361040052610c2c565b63ba0876528118610cb757606436106123d6576024358060a01c6123d6576103e0526044358060a01c6123d657610400525b600435156123d65760403661042037610c46610460611e7b565b610460805161042052602081015161044052506004356040526104205160605261044051608052610c786104806121b0565b610480516104605261046051156123d65761046051610280526004356102a0526103e0516102c052610400516102e052610cb0612232565b6020610460f35b633ee352fc8118610cf557600436106123d657610cd56103e0611e7b565b6103e0506001546103e052600254610400526003546104205260606103e0f35b63ccaf0c308118610d6057600436106123d65760a060206123e86000396000516370a082316102205230610240526020610220602461023c845afa610d3f573d600060003e3d6000fd5b60203d106123d657610220905051604052610d5b61026061179b565b610260f35b63f49ec3108118610ea657602436106123d6576004358060a01c6123d6576060524262093a8081049050600181038181116123d6579050608052600a60605160205260005260406000205460a05261ffff60a0511660c05260805160c0511115610dd957600960605160205260005260406000205460a0525b60603660e03760a051604052610df061014061148d565b610140805160c052602081015160e0526040810151610100526060810151610120525060c05115610e5f5760e0514262093a808104905062093a8081028162093a808204186123d6579050610100518082038281116123d657905090508082018281106123d6579050905060e0525b6101205160e0518082028115838383041417156123d6579050905060e0516008548082018281106123d6579050905080156123d65780820490509050610140526020610140f35b63c445c9388118610ee757600436106123d6576001546002548082018281106123d657905090506003548082018281106123d6579050905060405260206040f35b634fdf5d1d8118610fda57604436106123d6576004358060a01c6123d6576040526024358060a01c6123d65760605260045433186123d65760206123e8600039600051604051146123d6576040516370a0823160a0523060c052602060a0602460bc845afa610f5b573d600060003e3d6000fd5b60203d106123d65760a090505160805260405163a9059cbb60a05260605160c05260805160e052602060a0604460bc6000855af1610f9e573d600060003e3d6000fd5b3d610fb557803b156123d657600161010052610fcd565b60203d106123d65760a0518060011c6123d657610100525b610100905051156123d657005b633047ce9d811861104b57602436106123d65760045433186123d6576101f46004351015611009576000611012565b6107d060043511155b156123d6576004356006557f6717373928cccf59cc9912055cfa8db86e7085b95c94c15862b121114aa333be60043560405260206040a1005b631bf93f8681186110a357602436106123d65760045433186123d657600435156123d6576004356008557fa1eced997ca08ff4a574f4f14ce5dfcb37e8bde7f90a609f48f0c86edf1224ee60043560405260206040a1005b63fd066ecc81186110fe57602436106123d6576004358060a01c6123d65760405260045433186123d6576040516005556040517fe7b5cc087e6e47e33e86bdfe4720b7e849891938b18ff6e0c3f92299de79e60c60006060a2005b63759be10c811861114c57600436106123d65760055433186123d657600060055533600455337fafe23f9e1f603b288748a507d5a993957e9f14313a5889d5a070851299939d5960006040a2005b6330bcd67b81186111c257602436106123d6576004358060a01c6123d657604052600454331861117d576001611184565b6007543318155b156123d657604051156123d6576040516007556040517fcb7ef3e545f5cdb893f5c568ba710fe08f336375a2d9fd66e161033f8fc09ef360006060a2005b637b2aab0381186111e157600436106123d65760005460405260206040f35b6388a8d602811861120057600436106123d65760045460405260206040f35b63770817ec811861121f57600436106123d65760055460405260206040f35b6318f7b782811861123e57600436106123d65760065460405260206040f35b6361d027b3811861125d57600436106123d65760075460405260206040f35b63c5c91533811861127c57600436106123d65760085460405260206040f35b6318160ddd811861129b57600436106123d657600b5460405260206040f35b6370a0823181186112d657602436106123d6576004358060a01c6123d657604052600c60405160205260005260406000205460605260206060f35b63dd62ed3e811861133057604436106123d6576004358060a01c6123d6576040526024358060a01c6123d657606052600d604051602052600052604060002080606051602052600052604060002090505460805260206080f35b6306fdde0381186113b857600436106123d65760208060805260126040527f5374616b656420596561726e204574686572000000000000000000000000000060605260408160800181518082526020830160208301815181525050508051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506080f35b6395d89b41811861144057600436106123d65760208060805260076040527f73742d794554480000000000000000000000000000000000000000000000000060605260408160800181518082526020830160208301815181525050508051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506080f35b63313ce567811861145e57600436106123d657601260405260206040f35b6338d52e0f811861148557600436106123d65760206123e860003960005160405260206040f35b505b60006000fd5b61ffff60405116815266ffffffffffffff6040518060101c905016602082015266ffffffffffffff6040518060481c90501660408201526040518060801c9050606082015250565b61ffff60405111156114e857600061152f565b66ffffffffffffff606051111561150057600061152f565b66ffffffffffffff608051111561151857600061152f565b6fffffffffffffffffffffffffffffffff60a05111155b156123d65760a0518060801b90506080518060481b90506060518060101b9050604051171717815250565b600c60c051602052600052604060002054610120526101205161014052600161010051186115a0576101405160e0518082018281106123d65790509050610140526115ba565b6101405160e0518082038281116123d65790509050610140525b61014051600c60c0516020526000526040600020554262093a80810490506101605260803661018037600a60c05160205260005260406000205460405261160261020061148d565b61020080516101805260208101516101a05260408101516101c05260608101516101e05250610180511561163e57610180516101605111611641565b60005b1561166957600a60c051602052600052604060002054600960c0516020526000526040600020555b6101405161167e5760006101a05260006101e0525b6101e05115611760576101a051426101c0518082038281116123d657905090508082018281106123d657905090506101a052600161010051186117605760085461020052610120516101a0518082028115838383041417156123d65790509050610200518082028115838383041417156123d65790509050610140516101a051610200518082018281106123d657905090508082028115838383041417156123d65790509050610120516101a0518082028115838383041417156123d657905090508082038281116123d6579050905080156123d657808204905090506101a0525b610160516040526101a051606052426080526101405160a0526117846102006114d5565b61020051600a60c051602052600052604060002055565b60005460605242606051186117d357600154815260025460208201526003546040820152600060608201526000608082015250611d6d565b600060805260405160a05260015460c05260025460e0526003546101005260c05160e0518082018281106123d65790509050610100518082018281106123d65790509050610120526000610140524262093a808104905060605162093a80810490508082038281116123d65790509050610160526101605115611a4d5760016101605118611884576101005160e0518082018281106123d657905090506101005260c05160e052600060c052611a2c565b426060518082038281116123d65790509050610180526101005160e05160c0518082018281106123d657905090508082018281106123d65790509050610100526101205160a051116118df57600060e052600060c052611a2c565b60a051610120518082038281116123d657905090506101a0526101a0516006548082028115838383041417156123d65790509050612710810490506101c0526101a0516101c0518082038281116123d657905090506101a0526080516101c0518082018281106123d657905090506080526101a0518060ff1c6123d6576101405260a051610120526101a05162093a8081028162093a808204186123d65790506101805180156123d6578082049050905060e0526101805162093a8081038181116123d6579050610180526101a05160e0518082038281116123d657905090506101a0526101a0514262093a80810690508082028115838383041417156123d657905090506101805180156123d6578082049050905060c0526101a05160c0518082038281116123d657905090506101a052610100516101a0518082018281106123d65790509050610100525b4262093a808104905062093a8081028162093a808204186123d65790506060525b60605162093a80810690508062093a800362093a8081116123d657905061018052426060518082038281116123d657905090506101a05260e0516101a0518082028115838383041417156123d657905090506101805180156123d657808204905090506101c05260e0516101c0518082038281116123d6579050905060e052610100516101c0518082018281106123d65790509050610100526101205160a0511015611be2576101205160a0518082038281116123d657905090506101e052610140516101e0518060ff1c6123d65780820382811360008312186123d65790509050610140526101e05160c0511015611bc5576101e05160c0518082038281116123d657905090506101e052600060c0526101e05160e0511015611ba8576101e05160e0518082038281116123d657905090506101e052600060e052610100516101e0518082038281116123d6579050905061010052611cd7565b60e0516101e0518082038281116123d6579050905060e052611cd7565b60c0516101e0518082038281116123d6579050905060c052611cd7565b60a051610120518082038281116123d657905090506101e0526101e0516006548082028115838383041417156123d6579050905061271081049050610200526101e051610200518082038281116123d657905090506101e052608051610200518082018281106123d6579050905060805260016101605118611c7257620151804262093a80810690501115611c75565b60005b611c965760c0516101e0518082018281106123d6579050905060c052611caf565b60e0516101e0518082018281106123d6579050905060e0525b610140516101e0518060ff1c6123d65780820182811260008312186123d65790509050610140525b60006101e05260805115611d435761010051611cf9576080516101e052611d29565b608051600b548082028115838383041417156123d657905090506101005180156123d657808204905090506101e0525b610100516080518082018281106123d65790509050610100525b60c051815260e05160208201526101005160408201526101e0516060820152610140516080820152505b565b60a0366102203760206123e86000396000516370a082316102c052306102e05260206102c060246102dc845afa611dab573d600060003e3d6000fd5b60203d106123d6576102c0905051604052611dc761030061179b565b61030080516102205260208101516102405260408101516102605260608101516102805260808101516102a05250600b54610280518082018281106123d65790509050815261026051602082015250565b606051611e3a5766038d7ea4c68000604051106123d657604051815250611e79565b608051611e4b576000815250611e79565b6040516060518082028115838383041417156123d6579050905060805180156123d657808204905090508152505b565b60206123e86000396000516370a082316102a052306102c05260206102a060246102bc845afa611eb0573d600060003e3d6000fd5b60203d106123d6576102a09050516102805260a0366102a03761028051604052611edb61034061179b565b61034080516102a05260208101516102c05260408101516102e052606081015161030052608081015161032052506103205115611f5a577fabf5b9a9abf080b67be5bfa614a827845afc366da18173be4db7bf2761f2517e6102a051610340526102c051610360526102e05161038052610320516103a0526080610340a15b426000556102a0516001556102c0516002556102e051600355600b54610340526103005115611ffd5761034051610300518082018281106123d657905090506103405261034051600b55600754610360526103605160c0526103005160e052600161010052611fc761155a565b6103605160007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef61030051610380526020610380a35b6103405181526102e051602082015250565b600354610280518082018281106123d65790509050600355600b546102a0518082018281106123d65790509050600b556102c05160c0526102a05160e05260016101005261205b61155a565b60206123e86000396000516323b872dd6102e05233610300523061032052610280516103405260206102e060646102fc6000855af161209f573d600060003e3d6000fd5b3d6120b657803b156123d6576001610360526120cf565b60203d106123d6576102e0518060011c6123d657610360525b610360905051156123d6576102c051337fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7610280516102e0526102a0516103005260406102e0a36102c05160007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6102a0516102e05260206102e0a3565b60605161216f5766038d7ea4c68000604051106123d6576040518152506121ae565b6080516121805760008152506121ae565b6040516080518082028115838383041417156123d6579050905060605180156123d657808204905090508152505b565b6060516121c15760008152506121ef565b6040516080518082028115838383041417156123d6579050905060605180156123d657808204905090508152505b565b608051612202576000815250612230565b6040516060518082028115838383041417156123d6579050905060805180156123d657808204905090508152505b565b336102e0511461227457600d6102e051602052600052604060002080336020526000526040600020905080546102a0518082038281116123d657905090508155505b600354610280518082038281116123d65790509050600355600b546102a0518082038281116123d657905090506103005261030051600b556102e05160c0526102a05160e0526000610100526122c861155a565b66038d7ea4c67fff61030051116122e257610300516123d6575b60206123e860003960005163a9059cbb610320526102c0516103405261028051610360526020610320604461033c6000855af1612324573d600060003e3d6000fd5b3d61233b57803b156123d657600161038052612354565b60203d106123d657610320518060011c6123d657610380525b610380905051156123d65760006102e0517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6102a051610320526020610320a36102e0516102c051337ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db61028051610320526102a051610340526040610320a4565b600080fda165767970657283000307000b005b600080fd0000000000000000000000001bed97cbc3c24a4fb5c069c6e311a967386131f7

Deployed Bytecode

0x6003361161000c57611487565b60003560e01c346123d65763a9059cbb81186100d157604436106123d6576004358060a01c6123d65761028052610280511561004e5730610280511415610051565b60005b156123d65760243515610091573360c05260243560e05260006101005261007661155a565b6102805160c05260243560e05260016101005261009161155a565b61028051337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6024356102a05260206102a0a360016102a05260206102a0f35b6323b872dd81186101d657606436106123d6576004358060a01c6123d657610280526024358060a01c6123d6576102a0526102a0511561011757306102a051141561011a565b60005b156123d657600d61028051602052600052604060002080336020526000526040600020905080546044358082038281116123d6579050905081555060443515610193576102805160c05260443560e05260006101005261017861155a565b6102a05160c05260443560e05260016101005261019361155a565b6102a051610280517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6044356102c05260206102c0a360016102c05260206102c0f35b63095ea7b3811861025d57604436106123d6576004358060a01c6123d657604052604051156123d657602435600d336020526000526040600020806040516020526000526040600020905055604051337f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560243560605260206060a3600160605260206060f35b6339509351811861031857604436106123d6576004358060a01c6123d657604052604051156123d657600d3360205260005260406000208060405160205260005260406000209050546024358082018281106123d65790509050606052606051600d336020526000526040600020806040516020526000526040600020905055604051337f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560605160805260206080a3600160805260206080f35b63a457c2d781186103ef57604436106123d6576004358060a01c6123d657604052604051156123d657600d3360205260005260406000208060405160205260005260406000209050546060526060516024351161038b576060516024358082038281116123d65790509050606052610391565b60006060525b606051600d336020526000526040600020806040516020526000526040600020905055604051337f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560605160805260206080a3600160805260206080f35b6301e1d114811861042e57600436106123d6576040366103a0376104146103e0611d6f565b6103e080516103a05260208101516103c0525060206103c0f35b63c6e6f59281186104cf57602436106123d6576040366103a0376104536103e0611d6f565b6103e080516103a05260208101516103c052506103a05161047f576004356103e05260206103e06104cd565b6103c0516104975760006103e05260206103e06104cd565b6004356103a0518082028115838383041417156123d657905090506103c05180156123d657808204905090506103e05260206103e05bf35b6307a2d13a811861057057602436106123d6576040366103a0376104f46103e0611d6f565b6103e080516103a05260208101516103c052506103a051610520576004356103e05260206103e061056e565b6103c0516105385760006103e05260206103e061056e565b6004356103c0518082028115838383041417156123d657905090506103a05180156123d657808204905090506103e05260206103e05bf35b63402d267d81186105bb57602436106123d6576004358060a01c6123d6576040527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60605260206060f35b63ef8b30f7811861061957602436106123d6576040366103a0376105e06103e0611d6f565b6103e080516103a05260208101516103c0525060206004356040526103a0516060526103c0516080526106146103e0611e18565b6103e0f35b63b6b55f25811861063657602436106123d657336103e052610659565b636e553f6581186106dc57604436106123d6576024358060a01c6123d6576103e0525b600435156123d65760403661040037610673610440611e7b565b6104408051610400526020810151610420525060043560405261040051606052610420516080526106a5610460611e18565b610460516104405261044051156123d65760043561028052610440516102a0526103e0516102c0526106d561200f565b6020610440f35b63c63d75b6811861072757602436106123d6576004358060a01c6123d6576040527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60605260206060f35b63b3d7f6b9811861078557602436106123d6576040366103a03761074c6103e0611d6f565b6103e080516103a05260208101516103c0525060206004356040526103a0516060526103c0516080526107806103e061214d565b6103e0f35b63a0712d6881186107a257602436106123d657336103e0526107c5565b6394bf804d811861084857604436106123d6576024358060a01c6123d6576103e0525b600435156123d657604036610400376107df610440611e7b565b61044080516104005260208101516104205250600435604052610400516060526104205160805261081161046061214d565b610460516104405261044051156123d65761044051610280526004356102a0526103e0516102c05261084161200f565b6020610440f35b63ce96cb77811861092757602436106123d6576004358060a01c6123d6576103a0526040366103c03761087c610400611d6f565b61040080516103c05260208101516103e05250600c6103a051602052600052604060002054610400526103c051610400518082038281116123d657905090506104205266038d7ea4c67fff6104205111156108d85760006108df565b6104205115155b15610900576103c05166038d7ea4c6800081038181116123d6579050610400525b6020610400516040526103c0516060526103e0516080526109226104406121b0565b610440f35b630a28a477811861098557602436106123d6576040366103a03761094c6103e0611d6f565b6103e080516103a05260208101516103c0525060206004356040526103a0516060526103c0516080526109806103e06121f1565b6103e0f35b632e1a7d4d81186109a757602436106123d657336103e0523361040052610a04565b62f714ce81186109d257604436106123d6576024358060a01c6123d6576103e0523361040052610a04565b63b460af948118610a8f57606436106123d6576024358060a01c6123d6576103e0526044358060a01c6123d657610400525b600435156123d65760403661042037610a1e610460611e7b565b610460805161042052602081015161044052506004356040526104205160605261044051608052610a506104806121f1565b610480516104605261046051156123d65760043561028052610460516102a0526103e0516102c052610400516102e052610a88612232565b6020610460f35b63d905777e8118610b4e57602436106123d6576004358060a01c6123d6576103a0526040366103c037610ac3610400611d6f565b61040080516103c05260208101516103e05250600c6103a051602052600052604060002054610400526103c051610400518082038281116123d657905090506104205266038d7ea4c67fff610420511115610b1f576000610b26565b6104205115155b15610b47576103c05166038d7ea4c6800081038181116123d6579050610400525b6020610400f35b634cdad5068118610bac57602436106123d6576040366103a037610b736103e0611d6f565b6103e080516103a05260208101516103c0525060206004356040526103a0516060526103c051608052610ba76103e06121b0565b6103e0f35b63db006a758118610bce57602436106123d657336103e0523361040052610c2c565b637bde82f28118610bfa57604436106123d6576024358060a01c6123d6576103e0523361040052610c2c565b63ba0876528118610cb757606436106123d6576024358060a01c6123d6576103e0526044358060a01c6123d657610400525b600435156123d65760403661042037610c46610460611e7b565b610460805161042052602081015161044052506004356040526104205160605261044051608052610c786104806121b0565b610480516104605261046051156123d65761046051610280526004356102a0526103e0516102c052610400516102e052610cb0612232565b6020610460f35b633ee352fc8118610cf557600436106123d657610cd56103e0611e7b565b6103e0506001546103e052600254610400526003546104205260606103e0f35b63ccaf0c308118610d6057600436106123d65760a060206123e86000396000516370a082316102205230610240526020610220602461023c845afa610d3f573d600060003e3d6000fd5b60203d106123d657610220905051604052610d5b61026061179b565b610260f35b63f49ec3108118610ea657602436106123d6576004358060a01c6123d6576060524262093a8081049050600181038181116123d6579050608052600a60605160205260005260406000205460a05261ffff60a0511660c05260805160c0511115610dd957600960605160205260005260406000205460a0525b60603660e03760a051604052610df061014061148d565b610140805160c052602081015160e0526040810151610100526060810151610120525060c05115610e5f5760e0514262093a808104905062093a8081028162093a808204186123d6579050610100518082038281116123d657905090508082018281106123d6579050905060e0525b6101205160e0518082028115838383041417156123d6579050905060e0516008548082018281106123d6579050905080156123d65780820490509050610140526020610140f35b63c445c9388118610ee757600436106123d6576001546002548082018281106123d657905090506003548082018281106123d6579050905060405260206040f35b634fdf5d1d8118610fda57604436106123d6576004358060a01c6123d6576040526024358060a01c6123d65760605260045433186123d65760206123e8600039600051604051146123d6576040516370a0823160a0523060c052602060a0602460bc845afa610f5b573d600060003e3d6000fd5b60203d106123d65760a090505160805260405163a9059cbb60a05260605160c05260805160e052602060a0604460bc6000855af1610f9e573d600060003e3d6000fd5b3d610fb557803b156123d657600161010052610fcd565b60203d106123d65760a0518060011c6123d657610100525b610100905051156123d657005b633047ce9d811861104b57602436106123d65760045433186123d6576101f46004351015611009576000611012565b6107d060043511155b156123d6576004356006557f6717373928cccf59cc9912055cfa8db86e7085b95c94c15862b121114aa333be60043560405260206040a1005b631bf93f8681186110a357602436106123d65760045433186123d657600435156123d6576004356008557fa1eced997ca08ff4a574f4f14ce5dfcb37e8bde7f90a609f48f0c86edf1224ee60043560405260206040a1005b63fd066ecc81186110fe57602436106123d6576004358060a01c6123d65760405260045433186123d6576040516005556040517fe7b5cc087e6e47e33e86bdfe4720b7e849891938b18ff6e0c3f92299de79e60c60006060a2005b63759be10c811861114c57600436106123d65760055433186123d657600060055533600455337fafe23f9e1f603b288748a507d5a993957e9f14313a5889d5a070851299939d5960006040a2005b6330bcd67b81186111c257602436106123d6576004358060a01c6123d657604052600454331861117d576001611184565b6007543318155b156123d657604051156123d6576040516007556040517fcb7ef3e545f5cdb893f5c568ba710fe08f336375a2d9fd66e161033f8fc09ef360006060a2005b637b2aab0381186111e157600436106123d65760005460405260206040f35b6388a8d602811861120057600436106123d65760045460405260206040f35b63770817ec811861121f57600436106123d65760055460405260206040f35b6318f7b782811861123e57600436106123d65760065460405260206040f35b6361d027b3811861125d57600436106123d65760075460405260206040f35b63c5c91533811861127c57600436106123d65760085460405260206040f35b6318160ddd811861129b57600436106123d657600b5460405260206040f35b6370a0823181186112d657602436106123d6576004358060a01c6123d657604052600c60405160205260005260406000205460605260206060f35b63dd62ed3e811861133057604436106123d6576004358060a01c6123d6576040526024358060a01c6123d657606052600d604051602052600052604060002080606051602052600052604060002090505460805260206080f35b6306fdde0381186113b857600436106123d65760208060805260126040527f5374616b656420596561726e204574686572000000000000000000000000000060605260408160800181518082526020830160208301815181525050508051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506080f35b6395d89b41811861144057600436106123d65760208060805260076040527f73742d794554480000000000000000000000000000000000000000000000000060605260408160800181518082526020830160208301815181525050508051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506080f35b63313ce567811861145e57600436106123d657601260405260206040f35b6338d52e0f811861148557600436106123d65760206123e860003960005160405260206040f35b505b60006000fd5b61ffff60405116815266ffffffffffffff6040518060101c905016602082015266ffffffffffffff6040518060481c90501660408201526040518060801c9050606082015250565b61ffff60405111156114e857600061152f565b66ffffffffffffff606051111561150057600061152f565b66ffffffffffffff608051111561151857600061152f565b6fffffffffffffffffffffffffffffffff60a05111155b156123d65760a0518060801b90506080518060481b90506060518060101b9050604051171717815250565b600c60c051602052600052604060002054610120526101205161014052600161010051186115a0576101405160e0518082018281106123d65790509050610140526115ba565b6101405160e0518082038281116123d65790509050610140525b61014051600c60c0516020526000526040600020554262093a80810490506101605260803661018037600a60c05160205260005260406000205460405261160261020061148d565b61020080516101805260208101516101a05260408101516101c05260608101516101e05250610180511561163e57610180516101605111611641565b60005b1561166957600a60c051602052600052604060002054600960c0516020526000526040600020555b6101405161167e5760006101a05260006101e0525b6101e05115611760576101a051426101c0518082038281116123d657905090508082018281106123d657905090506101a052600161010051186117605760085461020052610120516101a0518082028115838383041417156123d65790509050610200518082028115838383041417156123d65790509050610140516101a051610200518082018281106123d657905090508082028115838383041417156123d65790509050610120516101a0518082028115838383041417156123d657905090508082038281116123d6579050905080156123d657808204905090506101a0525b610160516040526101a051606052426080526101405160a0526117846102006114d5565b61020051600a60c051602052600052604060002055565b60005460605242606051186117d357600154815260025460208201526003546040820152600060608201526000608082015250611d6d565b600060805260405160a05260015460c05260025460e0526003546101005260c05160e0518082018281106123d65790509050610100518082018281106123d65790509050610120526000610140524262093a808104905060605162093a80810490508082038281116123d65790509050610160526101605115611a4d5760016101605118611884576101005160e0518082018281106123d657905090506101005260c05160e052600060c052611a2c565b426060518082038281116123d65790509050610180526101005160e05160c0518082018281106123d657905090508082018281106123d65790509050610100526101205160a051116118df57600060e052600060c052611a2c565b60a051610120518082038281116123d657905090506101a0526101a0516006548082028115838383041417156123d65790509050612710810490506101c0526101a0516101c0518082038281116123d657905090506101a0526080516101c0518082018281106123d657905090506080526101a0518060ff1c6123d6576101405260a051610120526101a05162093a8081028162093a808204186123d65790506101805180156123d6578082049050905060e0526101805162093a8081038181116123d6579050610180526101a05160e0518082038281116123d657905090506101a0526101a0514262093a80810690508082028115838383041417156123d657905090506101805180156123d6578082049050905060c0526101a05160c0518082038281116123d657905090506101a052610100516101a0518082018281106123d65790509050610100525b4262093a808104905062093a8081028162093a808204186123d65790506060525b60605162093a80810690508062093a800362093a8081116123d657905061018052426060518082038281116123d657905090506101a05260e0516101a0518082028115838383041417156123d657905090506101805180156123d657808204905090506101c05260e0516101c0518082038281116123d6579050905060e052610100516101c0518082018281106123d65790509050610100526101205160a0511015611be2576101205160a0518082038281116123d657905090506101e052610140516101e0518060ff1c6123d65780820382811360008312186123d65790509050610140526101e05160c0511015611bc5576101e05160c0518082038281116123d657905090506101e052600060c0526101e05160e0511015611ba8576101e05160e0518082038281116123d657905090506101e052600060e052610100516101e0518082038281116123d6579050905061010052611cd7565b60e0516101e0518082038281116123d6579050905060e052611cd7565b60c0516101e0518082038281116123d6579050905060c052611cd7565b60a051610120518082038281116123d657905090506101e0526101e0516006548082028115838383041417156123d6579050905061271081049050610200526101e051610200518082038281116123d657905090506101e052608051610200518082018281106123d6579050905060805260016101605118611c7257620151804262093a80810690501115611c75565b60005b611c965760c0516101e0518082018281106123d6579050905060c052611caf565b60e0516101e0518082018281106123d6579050905060e0525b610140516101e0518060ff1c6123d65780820182811260008312186123d65790509050610140525b60006101e05260805115611d435761010051611cf9576080516101e052611d29565b608051600b548082028115838383041417156123d657905090506101005180156123d657808204905090506101e0525b610100516080518082018281106123d65790509050610100525b60c051815260e05160208201526101005160408201526101e0516060820152610140516080820152505b565b60a0366102203760206123e86000396000516370a082316102c052306102e05260206102c060246102dc845afa611dab573d600060003e3d6000fd5b60203d106123d6576102c0905051604052611dc761030061179b565b61030080516102205260208101516102405260408101516102605260608101516102805260808101516102a05250600b54610280518082018281106123d65790509050815261026051602082015250565b606051611e3a5766038d7ea4c68000604051106123d657604051815250611e79565b608051611e4b576000815250611e79565b6040516060518082028115838383041417156123d6579050905060805180156123d657808204905090508152505b565b60206123e86000396000516370a082316102a052306102c05260206102a060246102bc845afa611eb0573d600060003e3d6000fd5b60203d106123d6576102a09050516102805260a0366102a03761028051604052611edb61034061179b565b61034080516102a05260208101516102c05260408101516102e052606081015161030052608081015161032052506103205115611f5a577fabf5b9a9abf080b67be5bfa614a827845afc366da18173be4db7bf2761f2517e6102a051610340526102c051610360526102e05161038052610320516103a0526080610340a15b426000556102a0516001556102c0516002556102e051600355600b54610340526103005115611ffd5761034051610300518082018281106123d657905090506103405261034051600b55600754610360526103605160c0526103005160e052600161010052611fc761155a565b6103605160007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef61030051610380526020610380a35b6103405181526102e051602082015250565b600354610280518082018281106123d65790509050600355600b546102a0518082018281106123d65790509050600b556102c05160c0526102a05160e05260016101005261205b61155a565b60206123e86000396000516323b872dd6102e05233610300523061032052610280516103405260206102e060646102fc6000855af161209f573d600060003e3d6000fd5b3d6120b657803b156123d6576001610360526120cf565b60203d106123d6576102e0518060011c6123d657610360525b610360905051156123d6576102c051337fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7610280516102e0526102a0516103005260406102e0a36102c05160007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6102a0516102e05260206102e0a3565b60605161216f5766038d7ea4c68000604051106123d6576040518152506121ae565b6080516121805760008152506121ae565b6040516080518082028115838383041417156123d6579050905060605180156123d657808204905090508152505b565b6060516121c15760008152506121ef565b6040516080518082028115838383041417156123d6579050905060605180156123d657808204905090508152505b565b608051612202576000815250612230565b6040516060518082028115838383041417156123d6579050905060805180156123d657808204905090508152505b565b336102e0511461227457600d6102e051602052600052604060002080336020526000526040600020905080546102a0518082038281116123d657905090508155505b600354610280518082038281116123d65790509050600355600b546102a0518082038281116123d657905090506103005261030051600b556102e05160c0526102a05160e0526000610100526122c861155a565b66038d7ea4c67fff61030051116122e257610300516123d6575b60206123e860003960005163a9059cbb610320526102c0516103405261028051610360526020610320604461033c6000855af1612324573d600060003e3d6000fd5b3d61233b57803b156123d657600161038052612354565b60203d106123d657610320518060011c6123d657610380525b610380905051156123d65760006102e0517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6102a051610320526020610320a36102e0516102c051337ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db61028051610320526102a051610340526040610320a4565b600080fda165767970657283000307000b0000000000000000000000001bed97cbc3c24a4fb5c069c6e311a967386131f7

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

0000000000000000000000001bed97cbc3c24a4fb5c069c6e311a967386131f7

-----Decoded View---------------
Arg [0] : _asset (address): 0x1BED97CBC3c24A4fb5C069C6E311a967386131f7

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


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.