ETH Price: $2,969.13 (+2.36%)
Gas: 1 Gwei

Contract

0x9B142C2CDAb89941E9dcd0B6C1cf6dEa378A8D7C
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
Approve113787472020-12-03 9:07:251310 days ago1606986445IN
0x9B142C2C...a378A8D7C
0 ETH0.0018602141
Withdraw113336502020-11-26 11:11:481317 days ago1606389108IN
0x9B142C2C...a378A8D7C
0 ETH0.00708947179
Withdraw113275932020-11-25 12:47:271318 days ago1606308447IN
0x9B142C2C...a378A8D7C
0 ETH0.0027551456.00000247
Withdraw113274492020-11-25 12:11:551318 days ago1606306315IN
0x9B142C2C...a378A8D7C
0 ETH0.0032099550
Withdraw113245822020-11-25 1:27:501319 days ago1606267670IN
0x9B142C2C...a378A8D7C
0 ETH0.0021185633
Withdraw113235682020-11-24 21:43:291319 days ago1606254209IN
0x9B142C2C...a378A8D7C
0 ETH0.001353327.5
Deposit111908532020-11-04 13:11:341339 days ago1604495494IN
0x9B142C2C...a378A8D7C
0 ETH0.0025201733
Deposit111846832020-11-03 14:21:201340 days ago1604413280IN
0x9B142C2C...a378A8D7C
0 ETH0.00383842
Approve111803752020-11-02 22:29:491341 days ago1604356189IN
0x9B142C2C...a378A8D7C
0 ETH0.0016645137
Deposit111751472020-11-02 3:12:031342 days ago1604286723IN
0x9B142C2C...a378A8D7C
0 ETH0.0025583328
Approve111743072020-11-01 23:54:121342 days ago1604274852IN
0x9B142C2C...a378A8D7C
0 ETH0.0009915622
Deposit111660542020-10-31 17:25:131343 days ago1604165113IN
0x9B142C2C...a378A8D7C
0 ETH0.0018084717
Deposit111647212020-10-31 12:46:211343 days ago1604148381IN
0x9B142C2C...a378A8D7C
0 ETH0.0021869126
Deposit111641902020-10-31 10:53:091343 days ago1604141589IN
0x9B142C2C...a378A8D7C
0 ETH0.0011458915
Deposit111613162020-10-31 0:04:011344 days ago1604102641IN
0x9B142C2C...a378A8D7C
0 ETH0.0012684816.61
Deposit111612152020-10-30 23:43:281344 days ago1604101408IN
0x9B142C2C...a378A8D7C
0 ETH0.0012590916.5
Set Governance111533462020-10-29 18:34:241345 days ago1603996464IN
0x9B142C2C...a378A8D7C
0 ETH0.0015267935.99999999
Migrate Strategy111530822020-10-29 17:36:401345 days ago1603993000IN
0x9B142C2C...a378A8D7C
0 ETH0.037162825
Deposit111350512020-10-26 23:31:391348 days ago1603755099IN
0x9B142C2C...a378A8D7C
0 ETH0.0019955217
Add Strategy111350482020-10-26 23:30:181348 days ago1603755018IN
0x9B142C2C...a378A8D7C
0 ETH0.0032793817
Set Deposit Limi...111350462020-10-26 23:30:011348 days ago1603755001IN
0x9B142C2C...a378A8D7C
0 ETH0.0004645217
0x60a06135111349902020-10-26 23:19:481348 days ago1603754388IN
 Contract Creation
0 ETH0.0452646415

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x28328176...ba95014F9
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
Vyper_contract

Compiler Version
vyper:0.2.7

Optimization Enabled:
N/A

Other Settings:
GNU AGPLv3 license

Contract Source Code (Vyper language format)

#@version 0.2.7

CONTRACT_VERSION: constant(String[28]) = "0.1.1"

from vyper.interfaces import ERC20

implements: ERC20

interface DetailedERC20:
    def name() -> String[42]: view
    def symbol() -> String[20]: view
    def decimals() -> uint256: view

interface Strategy:
    def strategist() -> address: view
    def estimatedTotalAssets() -> uint256: view
    def withdraw(_amount: uint256): nonpayable
    def migrate(_newStrategy: address): nonpayable

event Transfer:
    sender: indexed(address)
    receiver: indexed(address)
    value: uint256

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


name: public(String[64])
symbol: public(String[32])
decimals: public(uint256)

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

token: public(ERC20)
governance: public(address)
guardian: public(address)
pendingGovernance: address

struct StrategyParams:
    performanceFee: uint256  # Strategist's fee (basis points)
    activation: uint256  # Activation block.number
    debtLimit: uint256  # Maximum borrow amount
    rateLimit: uint256  # Increase/decrease per block
    lastReport: uint256  # block.number of the last time a report occured
    totalDebt: uint256  # Total outstanding debt that Strategy has
    totalReturns: uint256  # Total returns that Strategy has realized for Vault

event StrategyAdded:
    strategy: indexed(address)
    debtLimit: uint256  # Maximum borrow amount
    rateLimit: uint256  # Increase/decrease per block
    performanceFee: uint256  # Strategist's fee (basis points)

event StrategyReported:
    strategy: indexed(address)
    returnAdded: uint256
    debtAdded: uint256
    totalReturn: uint256
    totalDebt: uint256
    debtLimit: uint256

# NOTE: Track the total for overhead targeting purposes
strategies: public(HashMap[address, StrategyParams])
MAXIMUM_STRATEGIES: constant(uint256) = 20

# Ordering that `withdraw` uses to determine which strategies to pull funds from
# NOTE: Does *NOT* have to match the ordering of all the current strategies that
#       exist, but it is recommended that it does or else withdrawal depth is
#       limited to only those inside the the queue.
# NOTE: Ordering is determined by governance, and should be balanced according
#       to risk, slippage, and/or volitility. Can also be ordered to increase the
#       withdrawal speed of a particular strategy.
# NOTE: The first time a ZERO_ADDRESS is encountered, it stops withdrawing
withdrawalQueue: public(address[MAXIMUM_STRATEGIES])

emergencyShutdown: public(bool)

depositLimit: public(uint256)  # Limit for totalAssets the Vault can hold
debtLimit: public(uint256)  # Debt limit for the Vault across all strategies
totalDebt: public(uint256)  # Amount of tokens that all strategies have borrowed
lastReport: public(uint256)  # Number of blocks since last report

rewards: public(address)  # Rewards contract where Governance fees are sent to
managementFee: public(uint256)  # Governance Fee for management of Vault (given to `rewards`)
performanceFee: public(uint256)  # Governance Fee for performance of Vault (given to `rewards`)
FEE_MAX: constant(uint256) = 10_000  # 100%, or 10k basis points
BLOCKS_PER_YEAR: constant(uint256) = 2_300_000

@external
def __init__(
    _token: address,
    _governance: address,
    _rewards: address,
    _nameOverride: String[64],
    _symbolOverride: String[32]
):
    self.token = ERC20(_token)
    if _nameOverride == "":
        self.name = concat("yearn ", DetailedERC20(_token).name())
    else:
        self.name = _nameOverride
    if _symbolOverride == "":
        self.symbol = concat("y", DetailedERC20(_token).symbol())
    else:
        self.symbol = _symbolOverride
    self.decimals = DetailedERC20(_token).decimals()
    self.governance = _governance
    self.rewards = _rewards
    self.guardian = msg.sender
    self.performanceFee = 450  # 4.5% of yield (per strategy)
    self.managementFee = 200  # 2% per year
    self.depositLimit = MAX_UINT256  # Start unlimited
    self.lastReport = block.number


@pure
@external
def version() -> String[28]:
    return CONTRACT_VERSION


# 2-phase commit for a change in governance
@external
def setGovernance(_governance: address):
    assert msg.sender == self.governance
    self.pendingGovernance = _governance


@external
def acceptGovernance():
    assert msg.sender == self.pendingGovernance
    self.governance = msg.sender


@external
def setRewards(_rewards: address):
    assert msg.sender == self.governance
    self.rewards = _rewards


@external
def setDepositLimit(_limit: uint256):
    assert msg.sender == self.governance
    self.depositLimit = _limit


@external
def setPerformanceFee(_fee: uint256):
    assert msg.sender == self.governance
    self.performanceFee = _fee


@external
def setManagementFee(_fee: uint256):
    assert msg.sender == self.governance
    self.managementFee = _fee


@external
def setGuardian(_guardian: address):
    assert msg.sender in [self.guardian, self.governance]
    self.guardian = _guardian


@external
def setEmergencyShutdown(_active: bool):
    """
    Activates Vault mode where all Strategies go into full withdrawal
    """
    assert msg.sender in [self.guardian, self.governance]
    self.emergencyShutdown = _active


@external
def setWithdrawalQueue(_queue: address[MAXIMUM_STRATEGIES]):
    assert msg.sender == self.governance
    for i in range(MAXIMUM_STRATEGIES):
        if _queue[i] == ZERO_ADDRESS and self.withdrawalQueue[i] == ZERO_ADDRESS:
            break
        assert self.strategies[_queue[i]].activation > 0
        self.withdrawalQueue[i] = _queue[i]


@internal
def _transfer(_from: address, _to: address, _value: uint256):
    # Protect people from accidentally sending their shares to bad places
    assert not (_to in [self, ZERO_ADDRESS])
    self.balanceOf[_from] -= _value
    self.balanceOf[_to] += _value
    log Transfer(_from, _to, _value)


@external
def transfer(_to: address, _value: uint256) -> bool:
    self._transfer(msg.sender, _to, _value)
    return True


@external
def transferFrom(_from : address, _to : address, _value : uint256) -> bool:
    if self.allowance[_from][msg.sender] < MAX_UINT256:  # Unlimited approval (saves an SSTORE)
       self.allowance[_from][msg.sender] -= _value
    self._transfer(_from, _to, _value)
    return True


@external
def approve(_spender : address, _value : uint256) -> bool:
    """
    @dev Approve the passed address to spend the specified amount of tokens on behalf of
         msg.sender. 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
    @param _spender The address which will spend the funds.
    @param _value The amount of tokens to be spent.
    """
    assert _value == 0 or self.allowance[msg.sender][_spender] == 0
    self.allowance[msg.sender][_spender] = _value
    log Approval(msg.sender, _spender, _value)
    return True


@view
@internal
def _totalAssets() -> uint256:
    return self.token.balanceOf(self) + self.totalDebt


@view
@external
def totalAssets() -> uint256:
    return self._totalAssets()


@view
@internal
def _balanceSheetOfStrategy(_strategy: address) -> uint256:
    return Strategy(_strategy).estimatedTotalAssets()


@view
@external
def balanceSheetOfStrategy(_strategy: address) -> uint256:
    return self._balanceSheetOfStrategy(_strategy)


@view
@external
def totalBalanceSheet(_strategies: address[2 * MAXIMUM_STRATEGIES]) -> uint256:
    """
    Measure the total balance sheet of this Vault, using the list of strategies
    given above. (2x the expected maximum is used for safety's sake)
    NOTE: The safety of this function depends *entirely* on the list of strategies
          given as the function argument. Care should be taken to choose this list
          to ensure that the estimate is accurate. No additional checking is used.
    NOTE: Guardian should use this value vs. `totalAssets()` to determine
          if a condition exists where the Vault is experiencing a dangerous
          'balance sheet' attack, leading Vault shares to be worth less than
          what their price on paper is (based on their debt)
    """
    balanceSheet: uint256 = self.token.balanceOf(self)

    for strategy in _strategies:
        if strategy == ZERO_ADDRESS:
            break
        balanceSheet += self._balanceSheetOfStrategy(strategy)

    return balanceSheet


@internal
def _issueSharesForAmount(_to: address, _amount: uint256) -> uint256:
    # NOTE: shares must be issued prior to taking on new collateral,
    #       or calculation will be wrong. This means that only *trusted*
    #       tokens (with no capability for exploitive behavior) can be used
    shares: uint256 = 0
    # HACK: Saves 2 SLOADs (~4000 gas)
    totalSupply: uint256 = self.totalSupply
    if totalSupply > 0:
        # Mint amount of shares based on what the Vault is managing overall
        shares = _amount * totalSupply / self._totalAssets()
    else:
        # No existing shares, so mint 1:1
        shares = _amount

    # Mint new shares
    self.totalSupply = totalSupply + shares
    self.balanceOf[_to] += shares
    log Transfer(ZERO_ADDRESS, _to, shares)

    return shares


@external
def deposit(_amount: uint256) -> uint256:
    assert not self.emergencyShutdown  # Deposits are locked out
    assert self._totalAssets() + _amount <= self.depositLimit  # Max deposit reached

    # NOTE: Measuring this based on the total outstanding debt that this contract
    #       has ("expected value") instead of the total balance sheet it has
    #       ("estimated value") has important security considerations, and is
    #       done intentionally. If this value were measured against external
    #       systems, it could be purposely manipulated by an attacker to withdraw
    #       more assets than they otherwise should be able to claim by redeeming
    #       their shares.
    #
    #       On deposit, this means that shares are issued against the total amount
    #       that the deposited capital can be given in service of the debt that
    #       Strategies assume. If that number were to be lower than the "expected value"
    #       at some future point, depositing shares via this method could entitle the
    #       depositor to *less* than the deposited value once the "realized value" is
    #       updated from further reportings by the Strategies to the Vaults.
    #
    #       Care should be taken by integrators to account for this discrepency,
    #       by using the view-only methods of this contract (both off-chain and
    #       on-chain) to determine if depositing into the Vault is a "good idea"

    # Issue new shares (needs to be done before taking deposit to be accurate)
    shares: uint256 = self._issueSharesForAmount(msg.sender, _amount)

    # Get new collateral
    reserve: uint256 = self.token.balanceOf(self)
    self.token.transferFrom(msg.sender, self, _amount)
    assert self.token.balanceOf(self) - reserve == _amount  # Deflationary token check

    return shares  # Just in case someone wants them


@view
@internal
def _shareValue(_shares: uint256) -> uint256:
    return (_shares * (self._totalAssets())) / self.totalSupply


@view
@internal
def _sharesForAmount(_amount: uint256) -> uint256:
    if self._totalAssets() > 0:
        return (_amount * self.totalSupply) / self._totalAssets()
    else:
        return 0


@view
@external
def maxAvailableShares() -> uint256:
    shares: uint256 = self._sharesForAmount(self.token.balanceOf(self))

    for strategy in self.withdrawalQueue:
        if strategy == ZERO_ADDRESS:
            break
        shares += self._sharesForAmount(self.strategies[strategy].totalDebt)

    return shares


@external
def withdraw(_shares: uint256):
    # Limit to only the shares they own
    assert _shares <= self.balanceOf[msg.sender]
    shares: uint256 = _shares  # May reduce this number below

    # NOTE: Measuring this based on the total outstanding debt that this contract
    #       has ("expected value") instead of the total balance sheet it has
    #       ("estimated value") has important security considerations, and is
    #       done intentionally. If this value were measured against external
    #       systems, it could be purposely manipulated by an attacker to withdraw
    #       more assets than they otherwise should be able to claim by redeeming
    #       their shares.
    #
    #       On withdrawal, this means that shares are redeemed against the total
    #       amount that the deposited capital had "realized" since the point it
    #       was deposited, up until the point it was withdrawn. If that number
    #       were to be higher than the "expected value" at some future point,
    #       withdrawing shares via this method could entitle the depositor to
    #       *more* than the expected value once the "realized value" is updated
    #       from further reportings by the Strategies to the Vaults.
    #
    #       Under exceptional scenarios, this could cause earlier withdrawals to
    #       earn "more" of the underlying assets than Users might otherwise be
    #       entitled to, if the Vault's estimated value were otherwise measured
    #       through external means, accounting for whatever exceptional scenarios
    #       exist for the Vault (that aren't covered by the Vault's own design)
    value: uint256 = self._shareValue(shares)

    if value > self.token.balanceOf(self):
        # We need to go get some from our strategies in the withdrawal queue
        # NOTE: This performs forced withdrawals from each strategy.
        for strategy in self.withdrawalQueue:
            if strategy == ZERO_ADDRESS:
                break  # We've exhausted the queue

            amountNeeded: uint256 = value - self.token.balanceOf(self)

            if amountNeeded == 0:
                break  # We're done withdrawing

            # NOTE: Don't withdraw more than the debt so that strategy can still
            #       continue to work based on the profits it has
            # NOTE: This means that user will lose out on any profits that each
            #       strategy in the queue would return on next harvest, benefitting others
            amountNeeded = min(amountNeeded, self.strategies[strategy].totalDebt)
            if amountNeeded == 0:
                continue  # Nothing to withdraw from this strategy, try the next one

            # Force withdraw amount from each strategy in the order set by governance
            before: uint256 = self.token.balanceOf(self)
            Strategy(strategy).withdraw(amountNeeded)
            withdrawn: uint256 = self.token.balanceOf(self) - before

            # Reduce the strategy's debt by the amount withdrawn ("realized returns")
            # NOTE: This doesn't add to returns as it's not earned by "normal means"
            self.strategies[strategy].totalDebt -= withdrawn
            self.totalDebt -= withdrawn

    # NOTE: We have withdrawn everything possible out of the withdrawal queue
    #       but we still don't have enough to fully pay them back, so adjust
    #       to the total amount we've freed up through forced withdrawals
    if value > self.token.balanceOf(self):
        value = self.token.balanceOf(self)
        shares = self._sharesForAmount(value)

    # Burn shares (full value of what is being withdrawn)
    self.totalSupply -= shares
    self.balanceOf[msg.sender] -= shares
    log Transfer(msg.sender, ZERO_ADDRESS, shares)

    # Withdraw remaining balance (minus fee)
    self.token.transfer(msg.sender, value)


@view
@external
def pricePerShare() -> uint256:
    return self._shareValue(10 ** self.decimals)


@internal
def _organizeWithdrawalQueue():
    # Reorganize based on premise that if there is an empty value between two
    # actual values, then the empty value should be replaced by the later value
    # NOTE: Relative ordering of non-zero values is maintained
    offset: uint256 = 0
    for idx in range(MAXIMUM_STRATEGIES):
        strategy: address = self.withdrawalQueue[idx]
        if strategy == ZERO_ADDRESS:
            offset += 1  # how many values we need to shift, always `<= idx`
        elif offset > 0:
            self.withdrawalQueue[idx-offset] = strategy
            self.withdrawalQueue[idx] = ZERO_ADDRESS


@external
def addStrategy(
    _strategy: address,
    _debtLimit: uint256,
    _rateLimit: uint256,
    _performanceFee: uint256,
):
    assert msg.sender == self.governance
    assert self.strategies[_strategy].activation == 0
    self.strategies[_strategy] = StrategyParams({
        performanceFee: _performanceFee,
        activation: block.number,
        debtLimit: _debtLimit,
        rateLimit: _rateLimit,
        lastReport: block.number,
        totalDebt: 0,
        totalReturns: 0,
    })
    self.debtLimit += _debtLimit
    log StrategyAdded(_strategy, _debtLimit, _rateLimit, _performanceFee)

    # queue is full
    assert self.withdrawalQueue[MAXIMUM_STRATEGIES-1] == ZERO_ADDRESS
    self.withdrawalQueue[MAXIMUM_STRATEGIES-1] = _strategy
    self._organizeWithdrawalQueue()


@external
def updateStrategyDebtLimit(
    _strategy: address,
    _debtLimit: uint256,
):
    assert msg.sender == self.governance
    assert self.strategies[_strategy].activation > 0
    self.debtLimit -= self.strategies[_strategy].debtLimit
    self.strategies[_strategy].debtLimit = _debtLimit
    self.debtLimit += _debtLimit


@external
def updateStrategyRateLimit(
    _strategy: address,
    _rateLimit: uint256,
):
    assert msg.sender == self.governance
    assert self.strategies[_strategy].activation > 0
    self.strategies[_strategy].rateLimit = _rateLimit


@external
def updateStrategyPerformanceFee(
    _strategy: address,
    _performanceFee: uint256,
):
    assert msg.sender == self.governance
    assert self.strategies[_strategy].activation > 0
    self.strategies[_strategy].performanceFee = _performanceFee


@external
def migrateStrategy(_oldVersion: address, _newVersion: address):
    """
    Only Governance can migrate a strategy to a new version
    NOTE: Strategy must successfully migrate all capital and positions to
          new Strategy, or else this will upset the balance of the Vault
    NOTE: The new strategy should be "empty" e.g. have no prior commitments
          to this Vault, otherwise it could have issues
    """
    assert msg.sender == self.governance

    assert self.strategies[_oldVersion].activation > 0
    assert self.strategies[_newVersion].activation == 0

    strategy: StrategyParams = self.strategies[_oldVersion]
    self.strategies[_oldVersion] = empty(StrategyParams)
    self.strategies[_newVersion] = strategy

    Strategy(_oldVersion).migrate(_newVersion)

    for idx in range(MAXIMUM_STRATEGIES):
        if self.withdrawalQueue[idx] == _oldVersion:
            self.withdrawalQueue[idx] = _newVersion
            return  # Don't need to reorder anything because we swapped


@external
def revokeStrategy(_strategy: address = msg.sender):
    """
    Governance can revoke a strategy
    OR
    A strategy can revoke itself (Emergency Exit Mode)
    """
    assert msg.sender in [_strategy, self.governance, self.guardian]
    self.debtLimit -= self.strategies[_strategy].debtLimit
    self.strategies[_strategy].debtLimit = 0


@external
def addStrategyToQueue(_strategy: address):
    assert msg.sender == self.governance
    # Must be a current strategy
    assert self.strategies[_strategy].activation > 0 and self.strategies[_strategy].totalDebt > 0
    # Check if queue is full
    assert self.withdrawalQueue[MAXIMUM_STRATEGIES-1] == ZERO_ADDRESS
    # Can't already be in the queue
    for strategy in self.withdrawalQueue:
        if strategy == ZERO_ADDRESS:
            break
        assert strategy != _strategy
    self.withdrawalQueue[MAXIMUM_STRATEGIES-1] = _strategy
    self._organizeWithdrawalQueue()


@external
def removeStrategyFromQueue(_strategy: address):
    # NOTE: We don't do this with revokeStrategy because it should still
    #       be possible to withdraw from it if it's unwinding
    assert msg.sender == self.governance
    for idx in range(MAXIMUM_STRATEGIES):
        if self.withdrawalQueue[idx] == _strategy:
            self.withdrawalQueue[idx] = ZERO_ADDRESS
            self._organizeWithdrawalQueue()
            return  # We found the right location and cleared it
    raise  # We didn't find the strategy in the queue


@view
@internal
def _debtOutstanding(_strategy: address) -> uint256:
    """
    Amount of tokens in strtaegy that Vault wants to recall
    """
    strategy_debtLimit: uint256 = self.strategies[_strategy].debtLimit
    strategy_totalDebt: uint256 = self.strategies[_strategy].totalDebt

    if self.emergencyShutdown:
        return strategy_totalDebt
    elif strategy_totalDebt <= strategy_debtLimit:
        return 0
    else:
        return strategy_totalDebt - strategy_debtLimit


@view
@external
def debtOutstanding(_strategy: address = msg.sender) -> uint256:
    return self._debtOutstanding(_strategy)


@view
@internal
def _creditAvailable(_strategy: address) -> uint256:
    """
    Amount of tokens in vault a strategy has access to as a credit line
    """
    if self.emergencyShutdown:
        return 0

    strategy_debtLimit: uint256 = self.strategies[_strategy].debtLimit
    strategy_totalDebt: uint256 = self.strategies[_strategy].totalDebt
    strategy_rateLimit: uint256 = self.strategies[_strategy].rateLimit
    strategy_lastReport: uint256 = self.strategies[_strategy].lastReport

    # Exhausted credit line
    if strategy_debtLimit <= strategy_totalDebt or self.debtLimit <= self.totalDebt:
        return 0

    # Start with debt limit left for the strategy
    available: uint256 = strategy_debtLimit - strategy_totalDebt

    # Adjust by the global debt limit left
    available = min(available, self.debtLimit - self.totalDebt)

    # Adjust by the rate limit algorithm (limits the step size per reporting period)
    blockDelta: uint256 = block.number - strategy_lastReport
    # NOTE: Protect against unnecessary overflow faults here
    # NOTE: Set `strategy_rateLimit` to a really high number to disable the rate limit
    # NOTE: *NEVER* set `strategy_rateLimit` to 0 or else this will always throw
    if available / strategy_rateLimit >= blockDelta:
        available = min(available, strategy_rateLimit * blockDelta)

    # Can only borrow up to what the contract has in reserve
    # NOTE: Running near 100% is discouraged
    return min(available, self.token.balanceOf(self))


@view
@external
def creditAvailable(_strategy: address = msg.sender) -> uint256:
    return self._creditAvailable(_strategy)


@view
@internal
def _expectedReturn(_strategy: address) -> uint256:
    strategy_lastReport: uint256 = self.strategies[_strategy].lastReport
    strategy_totalReturns: uint256 = self.strategies[_strategy].totalReturns
    strategy_activation: uint256 = self.strategies[_strategy].activation

    blockDelta: uint256 = (block.number - strategy_lastReport)
    if blockDelta > 0:
        return (strategy_totalReturns * blockDelta) / (block.number - strategy_activation)
    else:
        return 0  # Covers the scenario when block.number == strategy_activation


@view
@external
def expectedReturn(_strategy: address = msg.sender) -> uint256:
    return self._expectedReturn(_strategy)


@external
def report(_return: uint256) -> uint256:
    """
    Strategies call this.
    _return: amount Strategy has made on it's investment since its last report,
             and is free to be given back to Vault as earnings
    returns: amount of debt outstanding (iff totalDebt > debtLimit)
    """
    # NOTE: For approved strategies, this is the most efficient behavior.
    #       Strategy reports back what it has free (usually in terms of ROI)
    #       and then Vault "decides" here whether to take some back or give it more.
    #       Note that the most it can take is `_return`, and the most it can give is
    #       all of the remaining reserves. Anything outside of those bounds is abnormal
    #       behavior.
    # NOTE: All approved strategies must have increased diligience around
    #       calling this function, as abnormal behavior could become catastrophic

    # Only approved strategies can call this function
    assert self.strategies[msg.sender].activation > 0

    # Outstanding debt the Vault wants to take back from the Strategy (if any)
    debt: uint256 = self._debtOutstanding(msg.sender)

    # Issue new shares to cover fees
    # NOTE: In effect, this reduces overall share price by the combined fee
    governance_fee: uint256 = (
        self._totalAssets() * (block.number - self.lastReport) * self.managementFee
    ) / FEE_MAX / BLOCKS_PER_YEAR
    self.lastReport = block.number
    strategist_fee: uint256 = 0  # Only applies in certain conditions

    # NOTE: Applies if strategy is not shutting down, or it is but all debt paid off
    # NOTE: No fee is taken when a strategy is unwinding it's position, until all debt is paid
    if  _return > debt:
        strategist_fee = (
            (_return - debt) * self.strategies[msg.sender].performanceFee
        ) / FEE_MAX
        governance_fee += (_return - debt) * self.performanceFee / FEE_MAX

    # NOTE: This must be called prior to taking new collateral,
    #       or the calculation will be wrong!
    # NOTE: This must be done at the same time, to ensure the relative
    #       ratio of governance_fee : strategist_fee is kept intact
    total_fee: uint256 = governance_fee + strategist_fee
    reward: uint256 = self._issueSharesForAmount(self, total_fee)

    # Send the rewards out as new shares in this Vault
    if strategist_fee > 0:
        strategist_reward: uint256 = (strategist_fee * reward) / total_fee
        self._transfer(self, Strategy(msg.sender).strategist(), strategist_reward)
    # NOTE: Governance earns any dust leftover from flooring math above
    self._transfer(self, self.rewards, self.balanceOf[self])

    # Compute the line of credit the Vault is able to offer the Strategy (if any)
    credit: uint256 = self._creditAvailable(msg.sender)

    # Give/take balance to Strategy, based on the difference between the return and
    # the credit increase we are offering (if any)
    # NOTE: This is just used to adjust the balance of tokens between the Strategy and
    #       the Vault based on the strategy's debt limit (as well as the Vault's).
    if _return < credit:  # credit surplus, give to strategy
        self.token.transfer(msg.sender, credit - _return)
    elif _return > credit:  # credit deficit, take from strategy
        self.token.transferFrom(msg.sender, self, _return - credit)

    # else, don't do anything because it is performing well as is

    # Update the actual debt based on the full credit we are extending to the Strategy
    # or the returns if we are taking funds back
    # NOTE: credit + self.strategies[msg.sender].totalDebt is always < self.debtLimit
    # NOTE: At least one of `credit` or `debt` is always 0 (both can be 0)
    if credit > 0:
        self.strategies[msg.sender].totalDebt += credit
        self.totalDebt += credit

        # Returns are always "realized gains"
        self.strategies[msg.sender].totalReturns += _return

    elif debt > 0:  # We're repaying debt now, so there are no gains
        if _return <= debt:
            # Pay down our debt with profit
            # NOTE: Cannot return more than you borrowed
            self.strategies[msg.sender].totalDebt -= _return
            self.totalDebt -= _return
            debt -= _return  # Debt payment complete (to report back to strategy)

        else:
            # Finish off our debt payments here
            self.totalDebt -= debt
            self.strategies[msg.sender].totalDebt -= debt

            # Returns are always "realized gains" (after we have paid off our debt)
            self.strategies[msg.sender].totalReturns += _return - debt
            debt = 0  # All debts paid off (to report back to strategy)

    elif _return > 0:  # No debt to pay, nor credit to expand with, add to profit!
        self.strategies[msg.sender].totalReturns += _return

    # else, no credit/debt to manage, nor returns to report. Nothing really happened!

    # Update reporting time
    self.strategies[msg.sender].lastReport = block.number

    log StrategyReported(
        msg.sender,
        _return,
        credit,
        self.strategies[msg.sender].totalReturns,
        self.strategies[msg.sender].totalDebt,
        self.strategies[msg.sender].debtLimit,
    )

    if self.strategies[msg.sender].totalDebt == 0 or self.emergencyShutdown:
        # Take every last penny the Strategy has (Emergency Exit/revokeStrategy)
        # NOTE: This is different than `debt` in order to extract *all* of the returns
        return self._balanceSheetOfStrategy(msg.sender)
    else:
        # Otherwise, just return what we have as debt outstanding
        return debt


@internal
def erc20_safe_transfer(_token: address, _to: address, _value: uint256):
    # HACK: Used to handle non-compliant tokens like USDT
    _response: Bytes[32] = raw_call(
        _token,
        concat(
            method_id("transfer(address,uint256)"),
            convert(_to, bytes32),
            convert(_value, bytes32)
        ),
        max_outsize=32
    )
    if len(_response) > 0:
        assert convert(_response, bool), "Transfer failed!"


@external
def sweep(_token: address):
    # Can't be used to steal what this Vault is protecting
    assert _token != self.token.address
    self.erc20_safe_transfer(_token, self.governance, ERC20(_token).balanceOf(self))

Contract Security Audit

Contract ABI

[{"name":"Transfer","inputs":[{"type":"address","name":"sender","indexed":true},{"type":"address","name":"receiver","indexed":true},{"type":"uint256","name":"value","indexed":false}],"anonymous":false,"type":"event"},{"name":"Approval","inputs":[{"type":"address","name":"owner","indexed":true},{"type":"address","name":"spender","indexed":true},{"type":"uint256","name":"value","indexed":false}],"anonymous":false,"type":"event"},{"name":"StrategyAdded","inputs":[{"type":"address","name":"strategy","indexed":true},{"type":"uint256","name":"debtLimit","indexed":false},{"type":"uint256","name":"rateLimit","indexed":false},{"type":"uint256","name":"performanceFee","indexed":false}],"anonymous":false,"type":"event"},{"name":"StrategyReported","inputs":[{"type":"address","name":"strategy","indexed":true},{"type":"uint256","name":"returnAdded","indexed":false},{"type":"uint256","name":"debtAdded","indexed":false},{"type":"uint256","name":"totalReturn","indexed":false},{"type":"uint256","name":"totalDebt","indexed":false},{"type":"uint256","name":"debtLimit","indexed":false}],"anonymous":false,"type":"event"},{"outputs":[],"inputs":[{"type":"address","name":"_token"},{"type":"address","name":"_governance"},{"type":"address","name":"_rewards"},{"type":"string","name":"_nameOverride"},{"type":"string","name":"_symbolOverride"}],"stateMutability":"nonpayable","type":"constructor"},{"name":"version","outputs":[{"type":"string","name":""}],"inputs":[],"stateMutability":"pure","type":"function","gas":4489},{"name":"setGovernance","outputs":[],"inputs":[{"type":"address","name":"_governance"}],"stateMutability":"nonpayable","type":"function","gas":36248},{"name":"acceptGovernance","outputs":[],"inputs":[],"stateMutability":"nonpayable","type":"function","gas":36174},{"name":"setRewards","outputs":[],"inputs":[{"type":"address","name":"_rewards"}],"stateMutability":"nonpayable","type":"function","gas":36308},{"name":"setDepositLimit","outputs":[],"inputs":[{"type":"uint256","name":"_limit"}],"stateMutability":"nonpayable","type":"function","gas":36238},{"name":"setPerformanceFee","outputs":[],"inputs":[{"type":"uint256","name":"_fee"}],"stateMutability":"nonpayable","type":"function","gas":36268},{"name":"setManagementFee","outputs":[],"inputs":[{"type":"uint256","name":"_fee"}],"stateMutability":"nonpayable","type":"function","gas":36298},{"name":"setGuardian","outputs":[],"inputs":[{"type":"address","name":"_guardian"}],"stateMutability":"nonpayable","type":"function","gas":37655},{"name":"setEmergencyShutdown","outputs":[],"inputs":[{"type":"bool","name":"_active"}],"stateMutability":"nonpayable","type":"function","gas":37685},{"name":"setWithdrawalQueue","outputs":[],"inputs":[{"type":"address[20]","name":"_queue"}],"stateMutability":"nonpayable","type":"function","gas":749954},{"name":"transfer","outputs":[{"type":"bool","name":""}],"inputs":[{"type":"address","name":"_to"},{"type":"uint256","name":"_value"}],"stateMutability":"nonpayable","type":"function","gas":76439},{"name":"transferFrom","outputs":[{"type":"bool","name":""}],"inputs":[{"type":"address","name":"_from"},{"type":"address","name":"_to"},{"type":"uint256","name":"_value"}],"stateMutability":"nonpayable","type":"function","gas":113874},{"name":"approve","outputs":[{"type":"bool","name":""}],"inputs":[{"type":"address","name":"_spender"},{"type":"uint256","name":"_value"}],"stateMutability":"nonpayable","type":"function","gas":39259},{"name":"totalAssets","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":3643},{"name":"balanceSheetOfStrategy","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"address","name":"_strategy"}],"stateMutability":"view","type":"function","gas":2148},{"name":"totalBalanceSheet","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"address[40]","name":"_strategies"}],"stateMutability":"view","type":"function","gas":69686},{"name":"deposit","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"uint256","name":"_amount"}],"stateMutability":"nonpayable","type":"function","gas":91739},{"name":"maxAvailableShares","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":340711},{"name":"withdraw","outputs":[],"inputs":[{"type":"uint256","name":"_shares"}],"stateMutability":"nonpayable","type":"function","gas":1699710},{"name":"pricePerShare","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":10791},{"name":"addStrategy","outputs":[],"inputs":[{"type":"address","name":"_strategy"},{"type":"uint256","name":"_debtLimit"},{"type":"uint256","name":"_rateLimit"},{"type":"uint256","name":"_performanceFee"}],"stateMutability":"nonpayable","type":"function","gas":1425283},{"name":"updateStrategyDebtLimit","outputs":[],"inputs":[{"type":"address","name":"_strategy"},{"type":"uint256","name":"_debtLimit"}],"stateMutability":"nonpayable","type":"function","gas":111316},{"name":"updateStrategyRateLimit","outputs":[],"inputs":[{"type":"address","name":"_strategy"},{"type":"uint256","name":"_rateLimit"}],"stateMutability":"nonpayable","type":"function","gas":38368},{"name":"updateStrategyPerformanceFee","outputs":[],"inputs":[{"type":"address","name":"_strategy"},{"type":"uint256","name":"_performanceFee"}],"stateMutability":"nonpayable","type":"function","gas":38392},{"name":"migrateStrategy","outputs":[],"inputs":[{"type":"address","name":"_oldVersion"},{"type":"address","name":"_newVersion"}],"stateMutability":"nonpayable","type":"function","gas":1122309},{"name":"revokeStrategy","outputs":[],"inputs":[],"stateMutability":"nonpayable","type":"function"},{"name":"revokeStrategy","outputs":[],"inputs":[{"type":"address","name":"_strategy"}],"stateMutability":"nonpayable","type":"function"},{"name":"addStrategyToQueue","outputs":[],"inputs":[{"type":"address","name":"_strategy"}],"stateMutability":"nonpayable","type":"function","gas":1195242},{"name":"removeStrategyFromQueue","outputs":[],"inputs":[{"type":"address","name":"_strategy"}],"stateMutability":"nonpayable","type":"function","gas":23064468},{"name":"debtOutstanding","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function"},{"name":"debtOutstanding","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"address","name":"_strategy"}],"stateMutability":"view","type":"function"},{"name":"creditAvailable","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function"},{"name":"creditAvailable","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"address","name":"_strategy"}],"stateMutability":"view","type":"function"},{"name":"expectedReturn","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function"},{"name":"expectedReturn","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"address","name":"_strategy"}],"stateMutability":"view","type":"function"},{"name":"report","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"uint256","name":"_return"}],"stateMutability":"nonpayable","type":"function","gas":455050},{"name":"sweep","outputs":[],"inputs":[{"type":"address","name":"_token"}],"stateMutability":"nonpayable","type":"function","gas":9601},{"name":"name","outputs":[{"type":"string","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":8783},{"name":"symbol","outputs":[{"type":"string","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":7836},{"name":"decimals","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2441},{"name":"balanceOf","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"address","name":"arg0"}],"stateMutability":"view","type":"function","gas":2686},{"name":"allowance","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"address","name":"arg0"},{"type":"address","name":"arg1"}],"stateMutability":"view","type":"function","gas":2931},{"name":"totalSupply","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2531},{"name":"token","outputs":[{"type":"address","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2561},{"name":"governance","outputs":[{"type":"address","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2591},{"name":"guardian","outputs":[{"type":"address","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2621},{"name":"strategies","outputs":[{"type":"uint256","name":"performanceFee"},{"type":"uint256","name":"activation"},{"type":"uint256","name":"debtLimit"},{"type":"uint256","name":"rateLimit"},{"type":"uint256","name":"lastReport"},{"type":"uint256","name":"totalDebt"},{"type":"uint256","name":"totalReturns"}],"inputs":[{"type":"address","name":"arg0"}],"stateMutability":"view","type":"function","gas":9010},{"name":"withdrawalQueue","outputs":[{"type":"address","name":""}],"inputs":[{"type":"uint256","name":"arg0"}],"stateMutability":"view","type":"function","gas":2790},{"name":"emergencyShutdown","outputs":[{"type":"bool","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2711},{"name":"depositLimit","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2741},{"name":"debtLimit","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2771},{"name":"totalDebt","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2801},{"name":"lastReport","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2831},{"name":"rewards","outputs":[{"type":"address","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2861},{"name":"managementFee","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2891},{"name":"performanceFee","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2921}]

Deployed Bytecode

0x341561000a57600080fd5b600436101561001857613094565b600035601c526354fd4d5060005114156100b7576005610140527f302e312e31000000000000000000000000000000000000000000000000000000610160526101408051602001806101e08284600060045af161007457600080fd5b50506101e0518061020001818260206001820306601f820103905003368237505060206101c05260406101e0510160206001820306601f82010390506101c0f350005b63ab033ea960005114156100eb5760043560a01c156100d557600080fd5b60075433146100e357600080fd5b600435600955005b63238efcbc600051141561010d57600954331461010757600080fd5b33600755005b63ec38a86260005114156101415760043560a01c1561012b57600080fd5b600754331461013957600080fd5b600435601155005b63bdc8144b600051141561016557600754331461015d57600080fd5b600435600d55005b6370897b23600051141561018957600754331461018157600080fd5b600435601355005b63fe56e23260005114156101ad5760075433146101a557600080fd5b600435601255005b638a0dac4a60005114156102365760043560a01c156101cb57600080fd5b600854610160526007546101805260006101405261014061012060006002818352015b61012051602002610160015133141561020a576001835261021b565b5b81516001018083528114156101ee575b5050506101405160011461022e57600080fd5b600435600855005b6314c6440260005114156102bf5760043560011c1561025457600080fd5b600854610160526007546101805260006101405261014061012060006002818352015b61012051602002610160015133141561029357600183526102a4565b5b8151600101808352811415610277575b505050610140516001146102b757600080fd5b600435600c55005b639414841560005114156103f5576000610120525b610120516004013560a01c156102e957600080fd5b6020610120510161012052610280610120511015610306576102d4565b600754331461031457600080fd5b61014060006014818352015b6004610140516014811061033357600080fd5b6020020135151561036157610140516014811061034f57600080fd5b600b60c052602060c020015415610364565b60005b1561036e576103f1565b60006001600a6004610140516014811061038757600080fd5b602002013560e05260c052604060c02060c052602060c0200154116103ab57600080fd5b600461014051601481106103be57600080fd5b602002013561014051601481106103d457600080fd5b600b60c052602060c02001555b8151600101808352811415610320575b5050005b60001561050c575b6101a052610140526101605261018052306101e05260006102005260006101c0526101c061012060006002818352015b610120516020026101e0015161016051141561044c576001835261045d565b5b815160010180835281141561042d575b5050506101c0516001141561047157600080fd5b60036101405160e05260c052604060c0208054610180518082101561049557600080fd5b8082039050905081555060036101605160e05260c052604060c0208054610180518181830110156104c557600080fd5b80820190509050815550610180516101c05261016051610140517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206101c0a36101a051565b63a9059cbb60005114156105625760043560a01c1561052a57600080fd5b33610140526004356101605260243561018052610180516101605161014051600658016103fd565b600050600160005260206000f350005b6323b872dd60005114156106475760043560a01c1561058057600080fd5b60243560a01c1561059057600080fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460043560e05260c052604060c0203360e05260c052604060c02054101561060d57600460043560e05260c052604060c0203360e05260c052604060c02080546044358082101561060257600080fd5b808203905090508155505b600435610140526024356101605260443561018052610180516101605161014051600658016103fd565b600050600160005260206000f350005b63095ea7b360005114156106fd5760043560a01c1561066557600080fd5b6024351515610675576001610694565b60043360e05260c052604060c02060043560e05260c052604060c02054155b5b61069e57600080fd5b60243560043360e05260c052604060c02060043560e05260c052604060c0205560243561014052600435337f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9256020610140a3600160005260206000f350005b60001561076a575b6101405260206101e060246370a0823161016052306101805261017c6006545afa61072f57600080fd5b601f3d1161073c57600080fd5b6000506101e051600f5481818301101561075557600080fd5b80820190509050600052600051610140515650005b6301e1d11460005114156107945760065801610705565b610140526101405160005260206000f350005b6000156107e8575b610160526101405260206101e0600463efbb5cb06101805261019c610140515afa6107c657600080fd5b601f3d116107d357600080fd5b6000506101e051600052600051610160515650005b635ac22080600051141561082d5760043560a01c1561080657600080fd5b60043561014052610140516006580161079c565b6101a0526101a05160005260206000f350005b631d3249766000511415610951576000610120525b610120516004013560a01c1561085757600080fd5b602061012051016101205261050061012051101561087457610842565b60206101e060246370a0823161016052306101805261017c6006545afa61089a57600080fd5b601f3d116108a757600080fd5b6000506101e0516101405261018060006028818352015b6020610180510260040135610160526101605115156108dc57610940565b6101408051610140516101605161018051610160516101a0526101a0516006580161079c565b610200526101805261016052610140526102005181818301101561092557600080fd5b808201905090508152505b81516001018083528114156108be575b50506101405160005260206000f350005b600015610a95575b61018052610140526101605260006101a0526005546101c05260006101c05111156109f457610160516101c051808202821582848304141761099a57600080fd5b809050905090506101405161016051610180516101a0516101c05160065801610705565b6101e0526101c0526101a0526101805261016052610140526101e05180806109e557600080fd5b8204905090506101a0526109fd565b610160516101a0525b6101c0516101a051818183011015610a1457600080fd5b8082019050905060055560036101405160e05260c052604060c02080546101a051818183011015610a4457600080fd5b808201905090508155506101a0516101e0526101405160007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206101e0a36101a051600052600051610180515650005b63b6b55f256000511415610c0d57600c5415610ab057600080fd5b600d5460065801610705565b6101405261014051600435818183011015610ad657600080fd5b808201905090501115610ae857600080fd5b61014051336101605260043561018052610180516101605160065801610959565b6101e052610140526101e05161014052602061020060246370a0823161018052306101a05261019c6006545afa610b3f57600080fd5b601f3d11610b4c57600080fd5b6000506102005161016052602061024060646323b872dd61018052336101a052306101c0526004356101e05261019c60006006545af1610b8b57600080fd5b601f3d11610b9857600080fd5b60005061024050600435602061020060246370a0823161018052306101a05261019c6006545afa610bc857600080fd5b601f3d11610bd557600080fd5b600050610200516101605180821015610bed57600080fd5b8082039050905014610bfe57600080fd5b6101405160005260206000f350005b600015610c7f575b610160526101405261014051610140516101605160065801610705565b610180526101605261014052610180518082028215828483041417610c5657600080fd5b809050905090506005548080610c6b57600080fd5b820490509050600052600051610160515650005b600015610d36575b61016052610140526000610140516101605160065801610705565b610180526101605261014052610180511115610d2557610140516005548082028215828483041417610cd357600080fd5b8090509050905061014051610160516101805160065801610705565b6101a0526101805261016052610140526101a0518080610d0e57600080fd5b820490509050600052600051610160515650610d34565b60006000526000516101605156505b005b6375de29026000511415610e985760206101e060246370a0823161016052306101805261017c6006545afa610d6a57600080fd5b601f3d11610d7757600080fd5b6000506101e051610200526101405161016051610180516101a0516101c0516101e0516102005161020051610220526102205160065801610c87565b61028052610200526101e0526101c0526101a052610180526101605261014052610280516101405261018060006014818352015b61018051600b60c052602060c020015461016052610160511515610e0a57610e87565b61014080516101405161016051610180516005600a6101605160e05260c052604060c02060c052602060c02001546101a0526101a05160065801610c87565b6102005261018052610160526101405261020051818183011015610e6c57600080fd5b808201905090508152505b8151600101808352811415610de7575b50506101405160005260206000f350005b632e1a7d4d60005114156112f25760033360e05260c052604060c020546004351115610ec357600080fd5b60043561014052610140516101605161014051610180526101805160065801610c15565b6101e05261016052610140526101e05161016052602061020060246370a0823161018052306101a05261019c6006545afa610f2157600080fd5b601f3d11610f2e57600080fd5b600050610200516101605111156111545761024060006014818352015b61024051600b60c052602060c020015461022052610220511515610f6e57611151565b61016051602061030060246370a0823161028052306102a05261029c6006545afa610f9857600080fd5b601f3d11610fa557600080fd5b6000506103005180821015610fb957600080fd5b8082039050905061026052610260511515610fd357611151565b610260516005600a6102205160e05260c052604060c02060c052602060c0200154808211156110025780611004565b815b905090506102605261026051151561101b57611141565b602061032060246370a082316102a052306102c0526102bc6006545afa61104157600080fd5b601f3d1161104e57600080fd5b6000506103205161028052610220513b61106757600080fd5b600060006024632e1a7d4d6102a052610260516102c0526102bc6000610220515af161109257600080fd5b602061034060246370a082316102c052306102e0526102dc6006545afa6110b857600080fd5b601f3d116110c557600080fd5b6000506103405161028051808210156110dd57600080fd5b808203905090506102a0526005600a6102205160e05260c052604060c02060c052602060c0200180546102a0518082101561111757600080fd5b80820390509050815550600f80546102a0518082101561113657600080fd5b808203905090508155505b8151600101808352811415610f4b575b50505b602061020060246370a0823161018052306101a05261019c6006545afa61117a57600080fd5b601f3d1161118757600080fd5b600050610200516101605111156112305760206102a060246370a0823161022052306102405261023c6006545afa6111be57600080fd5b601f3d116111cb57600080fd5b6000506102a051610160526101405161016051610180516101a0516101c0516101e0516102005161016051610220526102205160065801610c87565b61028052610200526101e0526101c0526101a05261018052610160526101405261028051610140525b60058054610140518082101561124557600080fd5b8082039050905081555060033360e05260c052604060c0208054610140518082101561127057600080fd5b8082039050905081555061014051610180526000337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6020610180a36020610220604463a9059cbb61018052336101a052610160516101c05261019c60006006545af16112dc57600080fd5b601f3d116112e957600080fd5b60005061022050005b6399530b06600051141561133957604e6002541061130f57600080fd5b600254600a0a610140526101405160065801610c15565b6101a0526101a05160005260206000f350005b600015611426575b6101405260006101605261018060006014818352015b610180516014811061136857600080fd5b600b60c052602060c02001546101a0526101a05115156113a7576101608051600181818301101561139857600080fd5b8082019050905081525061140d565b600061016051111561140c576101a0516101805161016051808210156113cc57600080fd5b80820390509050601481106113e057600080fd5b600b60c052602060c0200155600061018051601481106113ff57600080fd5b600b60c052602060c02001555b5b5b8151600101808352811415611357575b505061014051565b630dd21b6c60005114156115565760043560a01c1561144457600080fd5b600754331461145257600080fd5b6001600a60043560e05260c052604060c02060c052602060c02001541561147857600080fd5b600a60043560e05260c052604060c02060c052602060c020606435815543600182015560243560028201556044356003820155436004820155600060058201556000600682015550600e80546024358181830110156114d657600080fd5b808201905090508155506024356101405260443561016052606435610180526004357f5ec27a4fa537fc86d0d17d84e0ee3172c9d253c78cc4ab5c69ee99c5f7084f516060610140a26013600b60c052602060c02001541561153757600080fd5b6004356013600b60c052602060c020015560065801611341565b600050005b63cd7d8f4f60005114156116225760043560a01c1561157457600080fd5b600754331461158257600080fd5b60006001600a60043560e05260c052604060c02060c052602060c0200154116115aa57600080fd5b600e80546002600a60043560e05260c052604060c02060c052602060c0200154808210156115d757600080fd5b808203905090508155506024356002600a60043560e05260c052604060c02060c052602060c0200155600e805460243581818301101561161657600080fd5b80820190509050815550005b6362fdbc9f60005114156116975760043560a01c1561164057600080fd5b600754331461164e57600080fd5b60006001600a60043560e05260c052604060c02060c052602060c02001541161167657600080fd5b6024356003600a60043560e05260c052604060c02060c052602060c0200155005b63d0194ed660005114156117095760043560a01c156116b557600080fd5b60075433146116c357600080fd5b60006001600a60043560e05260c052604060c02060c052602060c0200154116116eb57600080fd5b602435600a60043560e05260c052604060c02060c052602060c02055005b636cb56d1960005114156119675760043560a01c1561172757600080fd5b60243560a01c1561173757600080fd5b600754331461174557600080fd5b60006001600a60043560e05260c052604060c02060c052602060c02001541161176d57600080fd5b6001600a60243560e05260c052604060c02060c052602060c02001541561179357600080fd5b610140600a60043560e05260c052604060c0208060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015260038160c052602060c0200154826060015260048160c052602060c0200154826080015260058160c052602060c02001548260a0015260068160c052602060c02001548260c001525050600a60043560e05260c052604060c02060c052602060c0206000815560006001820155600060028201556000600382015560006004820155600060058201556000600682015550600a60243560e05260c052604060c02060c052602060c02061014080518255806020015160018301558060400151600283015580606001516003830155806080015160048301558060a0015160058301558060c00151600683015550506004353b6118d157600080fd5b60006000602463ce5494bb610220526024356102405261023c60006004355af16118fa57600080fd5b61022060006014818352015b600435610220516014811061191a57600080fd5b600b60c052602060c0200154141561195257602435610220516014811061194057600080fd5b600b60c052602060c020015560006000f35b5b8151600101808352811415611906575b5050005b63a0e4af9a600051141561197f5733610140526119b5565b63bb994d4860005114156119ad5760043560a01c1561199d57600080fd5b60206004610140376000506119b5565b600015611a79575b61014051610180526007546101a0526008546101c05260006101605261016061012060006003818352015b6101205160200261018001513314156119fc5760018352611a0d565b5b81516001018083528114156119e0575b50505061016051600114611a2057600080fd5b600e80546002600a6101405160e05260c052604060c02060c052602060c020015480821015611a4e57600080fd5b8082039050905081555060006002600a6101405160e05260c052604060c02060c052602060c0200155005b63f76e4caa6000511415611b835760043560a01c15611a9757600080fd5b6007543314611aa557600080fd5b60006001600a60043560e05260c052604060c02060c052602060c02001541115611aed5760006005600a60043560e05260c052604060c02060c052602060c020015411611af0565b60005b611af957600080fd5b6013600b60c052602060c020015415611b1157600080fd5b61016060006014818352015b61016051600b60c052602060c020015461014052610140511515611b4057611b62565b6004356101405118611b5157600080fd5b5b8151600101808352811415611b1d575b50506004356013600b60c052602060c020015560065801611341565b600050005b63b22439f56000511415611c345760043560a01c15611ba157600080fd5b6007543314611baf57600080fd5b61014060006014818352015b6004356101405160148110611bcf57600080fd5b600b60c052602060c02001541415611c1a5760006101405160148110611bf457600080fd5b600b60c052602060c02001556101405160065801611341565b6101405260005060006000f35b5b8151600101808352811415611bbb575b505060006000fd005b600015611cf1575b61016052610140526002600a6101405160e05260c052604060c02060c052602060c0200154610180526005600a6101405160e05260c052604060c02060c052602060c02001546101a052600c5415611ca3576101a051600052600051610160515650611cef565b610180516101a051111515611cc5576000600052600051610160515650611cee565b6101a0516101805180821015611cda57600080fd5b808203905090506000526000516101605156505b5b005b63bf3759b56000511415611d09573361014052611d3f565b63bdcf36bb6000511415611d375760043560a01c15611d2757600080fd5b6020600461014037600050611d3f565b600015611d6f575b6101405161014051610160526101605160065801611c3c565b6101c052610140526101c05160005260206000f350005b600015611f85575b6101605261014052600c5415611d965760006000526000516101605156505b6002600a6101405160e05260c052604060c02060c052602060c0200154610180526005600a6101405160e05260c052604060c02060c052602060c02001546101a0526003600a6101405160e05260c052604060c02060c052602060c02001546101c0526004600a6101405160e05260c052604060c02060c052602060c02001546101e0526101a05161018051111515611e30576001611e39565b600f54600e5411155b5b15611e4e5760006000526000516101605156505b610180516101a05180821015611e6357600080fd5b808203905090506102005261020051600e54600f5480821015611e8557600080fd5b8082039050905080821115611e9a5780611e9c565b815b9050905061020052436101e05180821015611eb657600080fd5b808203905090506102205261022051610200516101c0518080611ed857600080fd5b820490509050101515611f2557610200516101c051610220518082028215828483041417611f0557600080fd5b8090509050905080821115611f1a5780611f1c565b815b90509050610200525b6102005160206102c060246370a0823161024052306102605261025c6006545afa611f4f57600080fd5b601f3d11611f5c57600080fd5b6000506102c05180821115611f715780611f73565b815b90509050600052600051610160515650005b63112c1f9b6000511415611f9d573361014052611fd3565b63d76480136000511415611fcb5760043560a01c15611fbb57600080fd5b6020600461014037600050611fd3565b600015612003575b6101405161014051610160526101605160065801611d77565b6101c052610140526101c05160005260206000f350005b60001561210e575b61016052610140526004600a6101405160e05260c052604060c02060c052602060c0200154610180526006600a6101405160e05260c052604060c02060c052602060c02001546101a0526001600a6101405160e05260c052604060c02060c052602060c02001546101c05243610180518082101561208857600080fd5b808203905090506101e05260006101e05111156120fd576101a0516101e05180820282158284830414176120bb57600080fd5b80905090509050436101c051808210156120d457600080fd5b8082039050905080806120e657600080fd5b82049050905060005260005161016051565061210c565b60006000526000516101605156505b005b63d3406abd600051141561212657336101405261215c565b6333586b6760005114156121545760043560a01c1561214457600080fd5b602060046101403760005061215c565b60001561218c575b610140516101405161016052610160516006580161200b565b6101c052610140526101c05160005260206000f350005b63969b1cdb60005114156129b35760006001600a3360e05260c052604060c02060c052602060c0200154116121c057600080fd5b6101405133610160526101605160065801611c3c565b6101c052610140526101c05161014052610140516101605160065801610705565b61018052610160526101405261018051436010548082101561221857600080fd5b80820390509050808202821582848304141761223357600080fd5b80905090509050601254808202821582848304141761225157600080fd5b80905090509050612710808204905090506223186080820490509050610160524360105560006101805261014051600435111561234557600435610140518082101561229c57600080fd5b80820390509050600a3360e05260c052604060c02060c052602060c0205480820282158284830414176122ce57600080fd5b809050905090506127108082049050905061018052610160805160043561014051808210156122fc57600080fd5b80820390509050601354808202821582848304141761231a57600080fd5b809050905090506127108082049050905081818301101561233a57600080fd5b808201905090508152505b610160516101805181818301101561235c57600080fd5b808201905090506101a0526101405161016051610180516101a0516101c051306101e0526101a05161020052610200516101e05160065801610959565b610260526101c0526101a052610180526101605261014052610260516101c05260006101805111156124be57610180516101c05180820282158284830414176123e157600080fd5b809050905090506101a05180806123f757600080fd5b8204905090506101e05260206102606004631fe4a6866102005261021c335afa61242057600080fd5b601f3d1161242d57600080fd5b60005061026051610280526101405161016051610180516101a0516101c0516101e0516102005161022051610240516102605161028051306102a052610280516102c0526101e0516102e0526102e0516102c0516102a051600658016103fd565b61028052610260526102405261022052610200526101e0526101c0526101a0526101805261016052610140526000505b6101405161016051610180516101a0516101c051306101e0526011546102005260033060e05260c052604060c020546102205261022051610200516101e051600658016103fd565b6101c0526101a0526101805261016052610140526000506101405161016051610180516101a0516101c0516101e05133610200526102005160065801611d77565b610260526101e0526101c0526101a052610180526101605261014052610260516101e0526101e05160043510156125d85760206102a0604463a9059cbb6102005233610220526101e051600435808210156125a157600080fd5b808203905090506102405261021c60006006545af16125bf57600080fd5b601f3d116125cc57600080fd5b6000506102a050612647565b6101e05160043511156126465760206102c060646323b872dd61020052336102205230610240526004356101e0518082101561261357600080fd5b808203905090506102605261021c60006006545af161263157600080fd5b601f3d1161263e57600080fd5b6000506102c0505b5b60006101e05111156126e8576005600a3360e05260c052604060c02060c052602060c0200180546101e05181818301101561268157600080fd5b80820190509050815550600f80546101e0518181830110156126a257600080fd5b808201905090508155506006600a3360e05260c052604060c02060c052602060c0200180546004358181830110156126d957600080fd5b8082019050905081555061286e565b60006101405111156128295761014051600435111515612779576005600a3360e05260c052604060c02060c052602060c0200180546004358082101561272d57600080fd5b80820390509050815550600f80546004358082101561274b57600080fd5b8082039050905081555061014080516004358082101561276a57600080fd5b80820390509050815250612824565b600f8054610140518082101561278e57600080fd5b808203905090508155506005600a3360e05260c052604060c02060c052602060c02001805461014051808210156127c457600080fd5b808203905090508155506006600a3360e05260c052604060c02060c052602060c02001805460043561014051808210156127fd57600080fd5b8082039050905081818301101561281357600080fd5b808201905090508155506000610140525b61286d565b6000600435111561286c576006600a3360e05260c052604060c02060c052602060c02001805460043581818301101561286157600080fd5b808201905090508155505b5b5b436004600a3360e05260c052604060c02060c052602060c0200155600435610200526101e051610220526006600a3360e05260c052604060c02060c052602060c0200154610240526005600a3360e05260c052604060c02060c052602060c0200154610260526002600a3360e05260c052604060c02060c052602060c020015461028052337f4fe9b78b4a510a8ed0ae1dbed081f9447558c1dc31e6e898420adf01d39de17960a0610200a26005600a3360e05260c052604060c02060c052602060c02001541515612941576001612945565b600c545b5b156129a3576101405161016051610180516101a0516101c0516101e0513361020052610200516006580161079c565b610260526101e0526101c0526101a0526101805261016052610140526102605160005260206000f3506129b1565b6101405160005260206000f3505b005b600015612b56575b6101a05261014052610160526101805260006004610220527fa9059cbb000000000000000000000000000000000000000000000000000000006102405261022060048060208461028001018260208501600060045af15050805182019150506101605160208261028001015260208101905061018051602082610280010152602081019050806102805261028090508051602001806103208284600060045af1612a6457600080fd5b505060206103e0610320516103406000610140515af1612a8357600080fd5b60203d80821115612a945780612a96565b815b905090506103c0526103c08051602001806101c08284600060045af1612abb57600080fd5b505060006101c0511115612b50576101c0806020015160008251806020901315612ae457600080fd5b8091901215612af257600080fd5b806020036101000a820490509050905015151515612b4f576308c379a0610220526020610240526010610260527f5472616e73666572206661696c656421000000000000000000000000000000006102805261026050606461023cfd5b5b6101a051565b6301681a626000511415612c225760043560a01c15612b7457600080fd5b60065460043518612b8457600080fd5b60206101c060246370a0823161014052306101605261015c6004355afa612baa57600080fd5b601f3d11612bb757600080fd5b6000506101c0516101e0526101405161016051610180516101a0516101c0516101e05160043561020052600754610220526101e05161024052610240516102205161020051600658016129bb565b6101e0526101c0526101a052610180526101605261014052600050005b6306fdde036000511415612ccb5760008060c052602060c020610180602082540161012060006003818352015b82610120516020021115612c6257612c84565b61012051850154610120516020028501525b8151600101808352811415612c4f575b50505050505061018051806101a001818260206001820306601f82010390500336823750506020610160526040610180510160206001820306601f8201039050610160f350005b6395d89b416000511415612d745760018060c052602060c020610180602082540161012060006002818352015b82610120516020021115612d0b57612d2d565b61012051850154610120516020028501525b8151600101808352811415612cf8575b50505050505061018051806101a001818260206001820306601f82010390500336823750506020610160526040610180510160206001820306601f8201039050610160f350005b63313ce5676000511415612d905760025460005260206000f350005b6370a082316000511415612dca5760043560a01c15612dae57600080fd5b600360043560e05260c052604060c0205460005260206000f350005b63dd62ed3e6000511415612e225760043560a01c15612de857600080fd5b60243560a01c15612df857600080fd5b600460043560e05260c052604060c02060243560e05260c052604060c0205460005260206000f350005b6318160ddd6000511415612e3e5760055460005260206000f350005b63fc0c546a6000511415612e5a5760065460005260206000f350005b635aa6e6756000511415612e765760075460005260206000f350005b63452a93206000511415612e925760085460005260206000f350005b6339ebf8236000511415612f7e5760043560a01c15612eb057600080fd5b600a60043560e05260c052604060c0206101408080808460c052602060c0205481525050602081019050808060018560c052602060c020015481525050602081019050808060028560c052602060c020015481525050602081019050808060038560c052602060c020015481525050602081019050808060048560c052602060c020015481525050602081019050808060058560c052602060c020015481525050602081019050808060068560c052602060c02001548152505060e09050905060c05260c051610140f39050005b63c822adda6000511415612fb35760043560148110612f9c57600080fd5b600b60c052602060c020015460005260206000f350005b633403c2fc6000511415612fcf57600c5460005260206000f350005b63ecf708586000511415612feb57600d5460005260206000f350005b6318a1c4b6600051141561300757600e5460005260206000f350005b63fc7b9c18600051141561302357600f5460005260206000f350005b63c3535b52600051141561303f5760105460005260206000f350005b639ec5a894600051141561305b5760115460005260206000f350005b63a6f7f5d660005114156130775760125460005260206000f350005b638778878260005114156130935760135460005260206000f350005b5b60006000fd

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.