{"file_path":"Vyper_contract.vy","creation_status":"success","source_code":"# @version 0.2.4\n\"\"\"\n@title Voting Escrow\n@author Curve Finance\n@license MIT\n@notice Votes have a weight depending on time, so that users are\n        committed to the future of (whatever they are voting for)\n@dev Vote weight decays linearly over time. Lock time cannot be\n     more than `MAXTIME` (4 years).\n\"\"\"\n\n# Voting escrow to have time-weighted votes\n# Votes have a weight depending on time, so that users are committed\n# to the future of (whatever they are voting for).\n# The weight in this implementation is linear, and lock cannot be more than maxtime:\n# w ^\n# 1 +        /\n#   |      /\n#   |    /\n#   |  /\n#   |/\n# 0 +--------+------> time\n#       maxtime (4 years?)\n\nstruct Point:\n    bias: int128\n    slope: int128  # - dweight / dt\n    ts: uint256\n    blk: uint256  # block\n# We cannot really do block numbers per se b/c slope is per time, not per block\n# and per block could be fairly bad b/c Ethereum changes blocktimes.\n# What we can do is to extrapolate ***At functions\n\nstruct LockedBalance:\n    amount: int128\n    end: uint256\n\n\ninterface ERC20:\n    def decimals() -> uint256: view\n    def name() -> String[64]: view\n    def symbol() -> String[32]: view\n    def transfer(to: address, amount: uint256) -> bool: nonpayable\n    def transferFrom(spender: address, to: address, amount: uint256) -> bool: nonpayable\n\n\n# Interface for checking whether address belongs to a whitelisted\n# type of a smart wallet.\n# When new types are added - the whole contract is changed\n# The check() method is modifying to be able to use caching\n# for individual wallet addresses\ninterface SmartWalletChecker:\n    def check(addr: address) -> bool: nonpayable\n\nDEPOSIT_FOR_TYPE: constant(int128) = 0\nCREATE_LOCK_TYPE: constant(int128) = 1\nINCREASE_LOCK_AMOUNT: constant(int128) = 2\nINCREASE_UNLOCK_TIME: constant(int128) = 3\n\n\nevent CommitOwnership:\n    admin: address\n\nevent ApplyOwnership:\n    admin: address\n\nevent Deposit:\n    provider: indexed(address)\n    value: uint256\n    locktime: indexed(uint256)\n    type: int128\n    ts: uint256\n\nevent Withdraw:\n    provider: indexed(address)\n    value: uint256\n    ts: uint256\n\nevent Supply:\n    prevSupply: uint256\n    supply: uint256\n\n\nWEEK: constant(uint256) = 7 * 86400  # all future times are rounded by week\nMAXTIME: constant(uint256) = 4 * 365 * 86400  # 4 years\nMULTIPLIER: constant(uint256) = 10 ** 18\n\ntoken: public(address)\nsupply: public(uint256)\n\nlocked: public(HashMap[address, LockedBalance])\n\nepoch: public(uint256)\npoint_history: public(Point[100000000000000000000000000000])  # epoch -> unsigned point\nuser_point_history: public(HashMap[address, Point[1000000000]])  # user -> Point[user_epoch]\nuser_point_epoch: public(HashMap[address, uint256])\nslope_changes: public(HashMap[uint256, int128])  # time -> signed slope change\n\n# Aragon's view methods for compatibility\ncontroller: public(address)\ntransfersEnabled: public(bool)\n\nname: public(String[64])\nsymbol: public(String[32])\nversion: public(String[32])\ndecimals: public(uint256)\n\n# Checker for whitelisted (smart contract) wallets which are allowed to deposit\n# The goal is to prevent tokenizing the escrow\nfuture_smart_wallet_checker: public(address)\nsmart_wallet_checker: public(address)\n\nadmin: public(address)  # Can and will be a smart contract\nfuture_admin: public(address)\n\n\n@external\ndef __init__(token_addr: address, _name: String[64], _symbol: String[32], _version: String[32]):\n    \"\"\"\n    @notice Contract constructor\n    @param token_addr `ERC20CRV` token address\n    @param _name Token name\n    @param _symbol Token symbol\n    @param _version Contract version - required for Aragon compatibility\n    \"\"\"\n    self.admin = msg.sender\n    self.token = token_addr\n    self.point_history[0].blk = block.number\n    self.point_history[0].ts = block.timestamp\n    self.controller = msg.sender\n    self.transfersEnabled = True\n\n    _decimals: uint256 = ERC20(token_addr).decimals()\n    assert _decimals <= 255\n    self.decimals = _decimals\n\n    self.name = _name\n    self.symbol = _symbol\n    self.version = _version\n\n\n@external\ndef commit_transfer_ownership(addr: address):\n    \"\"\"\n    @notice Transfer ownership of VotingEscrow contract to `addr`\n    @param addr Address to have ownership transferred to\n    \"\"\"\n    assert msg.sender == self.admin  # dev: admin only\n    self.future_admin = addr\n    log CommitOwnership(addr)\n\n\n@external\ndef apply_transfer_ownership():\n    \"\"\"\n    @notice Apply ownership transfer\n    \"\"\"\n    assert msg.sender == self.admin  # dev: admin only\n    _admin: address = self.future_admin\n    assert _admin != ZERO_ADDRESS  # dev: admin not set\n    self.admin = _admin\n    log ApplyOwnership(_admin)\n\n\n@external\ndef commit_smart_wallet_checker(addr: address):\n    \"\"\"\n    @notice Set an external contract to check for approved smart contract wallets\n    @param addr Address of Smart contract checker\n    \"\"\"\n    assert msg.sender == self.admin\n    self.future_smart_wallet_checker = addr\n\n\n@external\ndef apply_smart_wallet_checker():\n    \"\"\"\n    @notice Apply setting external contract to check approved smart contract wallets\n    \"\"\"\n    assert msg.sender == self.admin\n    self.smart_wallet_checker = self.future_smart_wallet_checker\n\n\n@internal\ndef assert_not_contract(addr: address):\n    \"\"\"\n    @notice Check if the call is from a whitelisted smart contract, revert if not\n    @param addr Address to be checked\n    \"\"\"\n    if addr != tx.origin:\n        checker: address = self.smart_wallet_checker\n        if checker != ZERO_ADDRESS:\n            if SmartWalletChecker(checker).check(addr):\n                return\n        raise \"Smart contract depositors not allowed\"\n\n\n@external\n@view\ndef get_last_user_slope(addr: address) -> int128:\n    \"\"\"\n    @notice Get the most recently recorded rate of voting power decrease for `addr`\n    @param addr Address of the user wallet\n    @return Value of the slope\n    \"\"\"\n    uepoch: uint256 = self.user_point_epoch[addr]\n    return self.user_point_history[addr][uepoch].slope\n\n\n@external\n@view\ndef user_point_history__ts(_addr: address, _idx: uint256) -> uint256:\n    \"\"\"\n    @notice Get the timestamp for checkpoint `_idx` for `_addr`\n    @param _addr User wallet address\n    @param _idx User epoch number\n    @return Epoch time of the checkpoint\n    \"\"\"\n    return self.user_point_history[_addr][_idx].ts\n\n\n@external\n@view\ndef locked__end(_addr: address) -> uint256:\n    \"\"\"\n    @notice Get timestamp when `_addr`'s lock finishes\n    @param _addr User wallet\n    @return Epoch time of the lock end\n    \"\"\"\n    return self.locked[_addr].end\n\n\n@internal\ndef _checkpoint(addr: address, old_locked: LockedBalance, new_locked: LockedBalance):\n    \"\"\"\n    @notice Record global and per-user data to checkpoint\n    @param addr User's wallet address. No user checkpoint if 0x0\n    @param old_locked Pevious locked amount / end lock time for the user\n    @param new_locked New locked amount / end lock time for the user\n    \"\"\"\n    u_old: Point = empty(Point)\n    u_new: Point = empty(Point)\n    old_dslope: int128 = 0\n    new_dslope: int128 = 0\n    _epoch: uint256 = self.epoch\n\n    if addr != ZERO_ADDRESS:\n        # Calculate slopes and biases\n        # Kept at zero when they have to\n        if old_locked.end > block.timestamp and old_locked.amount > 0:\n            u_old.slope = old_locked.amount / MAXTIME\n            u_old.bias = u_old.slope * convert(old_locked.end - block.timestamp, int128)\n        if new_locked.end > block.timestamp and new_locked.amount > 0:\n            u_new.slope = new_locked.amount / MAXTIME\n            u_new.bias = u_new.slope * convert(new_locked.end - block.timestamp, int128)\n\n        # Read values of scheduled changes in the slope\n        # old_locked.end can be in the past and in the future\n        # new_locked.end can ONLY by in the FUTURE unless everything expired: than zeros\n        old_dslope = self.slope_changes[old_locked.end]\n        if new_locked.end != 0:\n            if new_locked.end == old_locked.end:\n                new_dslope = old_dslope\n            else:\n                new_dslope = self.slope_changes[new_locked.end]\n\n    last_point: Point = Point({bias: 0, slope: 0, ts: block.timestamp, blk: block.number})\n    if _epoch > 0:\n        last_point = self.point_history[_epoch]\n    last_checkpoint: uint256 = last_point.ts\n    # initial_last_point is used for extrapolation to calculate block number\n    # (approximately, for *At methods) and save them\n    # as we cannot figure that out exactly from inside the contract\n    initial_last_point: Point = last_point\n    block_slope: uint256 = 0  # dblock/dt\n    if block.timestamp > last_point.ts:\n        block_slope = MULTIPLIER * (block.number - last_point.blk) / (block.timestamp - last_point.ts)\n    # If last point is already recorded in this block, slope=0\n    # But that's ok b/c we know the block in such case\n\n    # Go over weeks to fill history and calculate what the current point is\n    t_i: uint256 = (last_checkpoint / WEEK) * WEEK\n    for i in range(255):\n        # Hopefully it won't happen that this won't get used in 5 years!\n        # If it does, users will be able to withdraw but vote weight will be broken\n        t_i += WEEK\n        d_slope: int128 = 0\n        if t_i > block.timestamp:\n            t_i = block.timestamp\n        else:\n            d_slope = self.slope_changes[t_i]\n        last_point.bias -= last_point.slope * convert(t_i - last_checkpoint, int128)\n        last_point.slope += d_slope\n        if last_point.bias < 0:  # This can happen\n            last_point.bias = 0\n        if last_point.slope < 0:  # This cannot happen - just in case\n            last_point.slope = 0\n        last_checkpoint = t_i\n        last_point.ts = t_i\n        last_point.blk = initial_last_point.blk + block_slope * (t_i - initial_last_point.ts) / MULTIPLIER\n        _epoch += 1\n        if t_i == block.timestamp:\n            last_point.blk = block.number\n            break\n        else:\n            self.point_history[_epoch] = last_point\n\n    self.epoch = _epoch\n    # Now point_history is filled until t=now\n\n    if addr != ZERO_ADDRESS:\n        # If last point was in this block, the slope change has been applied already\n        # But in such case we have 0 slope(s)\n        last_point.slope += (u_new.slope - u_old.slope)\n        last_point.bias += (u_new.bias - u_old.bias)\n        if last_point.slope < 0:\n            last_point.slope = 0\n        if last_point.bias < 0:\n            last_point.bias = 0\n\n    # Record the changed point into history\n    self.point_history[_epoch] = last_point\n\n    if addr != ZERO_ADDRESS:\n        # Schedule the slope changes (slope is going down)\n        # We subtract new_user_slope from [new_locked.end]\n        # and add old_user_slope to [old_locked.end]\n        if old_locked.end > block.timestamp:\n            # old_dslope was <something> - u_old.slope, so we cancel that\n            old_dslope += u_old.slope\n            if new_locked.end == old_locked.end:\n                old_dslope -= u_new.slope  # It was a new deposit, not extension\n            self.slope_changes[old_locked.end] = old_dslope\n\n        if new_locked.end > block.timestamp:\n            if new_locked.end > old_locked.end:\n                new_dslope -= u_new.slope  # old slope disappeared at this point\n                self.slope_changes[new_locked.end] = new_dslope\n            # else: we recorded it already in old_dslope\n\n        # Now handle user history\n        user_epoch: uint256 = self.user_point_epoch[addr] + 1\n\n        self.user_point_epoch[addr] = user_epoch\n        u_new.ts = block.timestamp\n        u_new.blk = block.number\n        self.user_point_history[addr][user_epoch] = u_new\n\n\n@internal\ndef _deposit_for(_addr: address, _value: uint256, unlock_time: uint256, locked_balance: LockedBalance, type: int128):\n    \"\"\"\n    @notice Deposit and lock tokens for a user\n    @param _addr User's wallet address\n    @param _value Amount to deposit\n    @param unlock_time New time when to unlock the tokens, or 0 if unchanged\n    @param locked_balance Previous locked amount / timestamp\n    \"\"\"\n    _locked: LockedBalance = locked_balance\n    supply_before: uint256 = self.supply\n\n    self.supply = supply_before + _value\n    old_locked: LockedBalance = _locked\n    # Adding to existing lock, or if a lock is expired - creating a new one\n    _locked.amount += convert(_value, int128)\n    if unlock_time != 0:\n        _locked.end = unlock_time\n    self.locked[_addr] = _locked\n\n    # Possibilities:\n    # Both old_locked.end could be current or expired (>/< block.timestamp)\n    # value == 0 (extend lock) or value > 0 (add to lock or extend lock)\n    # _locked.end > block.timestamp (always)\n    self._checkpoint(_addr, old_locked, _locked)\n\n    if _value != 0:\n        assert ERC20(self.token).transferFrom(_addr, self, _value)\n\n    log Deposit(_addr, _value, _locked.end, type, block.timestamp)\n    log Supply(supply_before, supply_before + _value)\n\n\n@external\ndef checkpoint():\n    \"\"\"\n    @notice Record global data to checkpoint\n    \"\"\"\n    self._checkpoint(ZERO_ADDRESS, empty(LockedBalance), empty(LockedBalance))\n\n\n@external\n@nonreentrant('lock')\ndef deposit_for(_addr: address, _value: uint256):\n    \"\"\"\n    @notice Deposit `_value` tokens for `_addr` and add to the lock\n    @dev Anyone (even a smart contract) can deposit for someone else, but\n         cannot extend their locktime and deposit for a brand new user\n    @param _addr User's wallet address\n    @param _value Amount to add to user's lock\n    \"\"\"\n    _locked: LockedBalance = self.locked[_addr]\n\n    assert _value > 0  # dev: need non-zero value\n    assert _locked.amount > 0, \"No existing lock found\"\n    assert _locked.end > block.timestamp, \"Cannot add to expired lock. Withdraw\"\n\n    self._deposit_for(_addr, _value, 0, self.locked[_addr], DEPOSIT_FOR_TYPE)\n\n\n@external\n@nonreentrant('lock')\ndef create_lock(_value: uint256, _unlock_time: uint256):\n    \"\"\"\n    @notice Deposit `_value` tokens for `msg.sender` and lock until `_unlock_time`\n    @param _value Amount to deposit\n    @param _unlock_time Epoch time when tokens unlock, rounded down to whole weeks\n    \"\"\"\n    self.assert_not_contract(msg.sender)\n    unlock_time: uint256 = (_unlock_time / WEEK) * WEEK  # Locktime is rounded down to weeks\n    _locked: LockedBalance = self.locked[msg.sender]\n\n    assert _value > 0  # dev: need non-zero value\n    assert _locked.amount == 0, \"Withdraw old tokens first\"\n    assert unlock_time > block.timestamp, \"Can only lock until time in the future\"\n    assert unlock_time <= block.timestamp + MAXTIME, \"Voting lock can be 4 years max\"\n\n    self._deposit_for(msg.sender, _value, unlock_time, _locked, CREATE_LOCK_TYPE)\n\n\n@external\n@nonreentrant('lock')\ndef increase_amount(_value: uint256):\n    \"\"\"\n    @notice Deposit `_value` additional tokens for `msg.sender`\n            without modifying the unlock time\n    @param _value Amount of tokens to deposit and add to the lock\n    \"\"\"\n    self.assert_not_contract(msg.sender)\n    _locked: LockedBalance = self.locked[msg.sender]\n\n    assert _value > 0  # dev: need non-zero value\n    assert _locked.amount > 0, \"No existing lock found\"\n    assert _locked.end > block.timestamp, \"Cannot add to expired lock. Withdraw\"\n\n    self._deposit_for(msg.sender, _value, 0, _locked, INCREASE_LOCK_AMOUNT)\n\n\n@external\n@nonreentrant('lock')\ndef increase_unlock_time(_unlock_time: uint256):\n    \"\"\"\n    @notice Extend the unlock time for `msg.sender` to `_unlock_time`\n    @param _unlock_time New epoch time for unlocking\n    \"\"\"\n    self.assert_not_contract(msg.sender)\n    _locked: LockedBalance = self.locked[msg.sender]\n    unlock_time: uint256 = (_unlock_time / WEEK) * WEEK  # Locktime is rounded down to weeks\n\n    assert _locked.end > block.timestamp, \"Lock expired\"\n    assert _locked.amount > 0, \"Nothing is locked\"\n    assert unlock_time > _locked.end, \"Can only increase lock duration\"\n    assert unlock_time <= block.timestamp + MAXTIME, \"Voting lock can be 4 years max\"\n\n    self._deposit_for(msg.sender, 0, unlock_time, _locked, INCREASE_UNLOCK_TIME)\n\n\n@external\n@nonreentrant('lock')\ndef withdraw():\n    \"\"\"\n    @notice Withdraw all tokens for `msg.sender`\n    @dev Only possible if the lock has expired\n    \"\"\"\n    _locked: LockedBalance = self.locked[msg.sender]\n    assert block.timestamp >= _locked.end, \"The lock didn't expire\"\n    value: uint256 = convert(_locked.amount, uint256)\n\n    old_locked: LockedBalance = _locked\n    _locked.end = 0\n    _locked.amount = 0\n    self.locked[msg.sender] = _locked\n    supply_before: uint256 = self.supply\n    self.supply = supply_before - value\n\n    # old_locked can have either expired <= timestamp or zero end\n    # _locked has only 0 end\n    # Both can have >= 0 amount\n    self._checkpoint(msg.sender, old_locked, _locked)\n\n    assert ERC20(self.token).transfer(msg.sender, value)\n\n    log Withdraw(msg.sender, value, block.timestamp)\n    log Supply(supply_before, supply_before - value)\n\n\n# The following ERC20/minime-compatible methods are not real balanceOf and supply!\n# They measure the weights for the purpose of voting, so they don't represent\n# real coins.\n\n@internal\n@view\ndef find_block_epoch(_block: uint256, max_epoch: uint256) -> uint256:\n    \"\"\"\n    @notice Binary search to estimate timestamp for block number\n    @param _block Block to find\n    @param max_epoch Don't go beyond this epoch\n    @return Approximate timestamp for block\n    \"\"\"\n    # Binary search\n    _min: uint256 = 0\n    _max: uint256 = max_epoch\n    for i in range(128):  # Will be always enough for 128-bit numbers\n        if _min >= _max:\n            break\n        _mid: uint256 = (_min + _max + 1) / 2\n        if self.point_history[_mid].blk <= _block:\n            _min = _mid\n        else:\n            _max = _mid - 1\n    return _min\n\n\n@external\n@view\ndef balanceOf(addr: address, _t: uint256 = block.timestamp) -> uint256:\n    \"\"\"\n    @notice Get the current voting power for `msg.sender`\n    @dev Adheres to the ERC20 `balanceOf` interface for Aragon compatibility\n    @param addr User wallet address\n    @param _t Epoch time to return voting power at\n    @return User voting power\n    \"\"\"\n    _epoch: uint256 = self.user_point_epoch[addr]\n    if _epoch == 0:\n        return 0\n    else:\n        last_point: Point = self.user_point_history[addr][_epoch]\n        last_point.bias -= last_point.slope * convert(_t - last_point.ts, int128)\n        if last_point.bias < 0:\n            last_point.bias = 0\n        return convert(last_point.bias, uint256)\n\n\n@external\n@view\ndef balanceOfAt(addr: address, _block: uint256) -> uint256:\n    \"\"\"\n    @notice Measure voting power of `addr` at block height `_block`\n    @dev Adheres to MiniMe `balanceOfAt` interface: https://github.com/Giveth/minime\n    @param addr User's wallet address\n    @param _block Block to calculate the voting power at\n    @return Voting power\n    \"\"\"\n    # Copying and pasting totalSupply code because Vyper cannot pass by\n    # reference yet\n    assert _block <= block.number\n\n    # Binary search\n    _min: uint256 = 0\n    _max: uint256 = self.user_point_epoch[addr]\n    for i in range(128):  # Will be always enough for 128-bit numbers\n        if _min >= _max:\n            break\n        _mid: uint256 = (_min + _max + 1) / 2\n        if self.user_point_history[addr][_mid].blk <= _block:\n            _min = _mid\n        else:\n            _max = _mid - 1\n\n    upoint: Point = self.user_point_history[addr][_min]\n\n    max_epoch: uint256 = self.epoch\n    _epoch: uint256 = self.find_block_epoch(_block, max_epoch)\n    point_0: Point = self.point_history[_epoch]\n    d_block: uint256 = 0\n    d_t: uint256 = 0\n    if _epoch < max_epoch:\n        point_1: Point = self.point_history[_epoch + 1]\n        d_block = point_1.blk - point_0.blk\n        d_t = point_1.ts - point_0.ts\n    else:\n        d_block = block.number - point_0.blk\n        d_t = block.timestamp - point_0.ts\n    block_time: uint256 = point_0.ts\n    if d_block != 0:\n        block_time += d_t * (_block - point_0.blk) / d_block\n\n    upoint.bias -= upoint.slope * convert(block_time - upoint.ts, int128)\n    if upoint.bias >= 0:\n        return convert(upoint.bias, uint256)\n    else:\n        return 0\n\n\n@internal\n@view\ndef supply_at(point: Point, t: uint256) -> uint256:\n    \"\"\"\n    @notice Calculate total voting power at some point in the past\n    @param point The point (bias/slope) to start search from\n    @param t Time to calculate the total voting power at\n    @return Total voting power at that time\n    \"\"\"\n    last_point: Point = point\n    t_i: uint256 = (last_point.ts / WEEK) * WEEK\n    for i in range(255):\n        t_i += WEEK\n        d_slope: int128 = 0\n        if t_i > t:\n            t_i = t\n        else:\n            d_slope = self.slope_changes[t_i]\n        last_point.bias -= last_point.slope * convert(t_i - last_point.ts, int128)\n        if t_i == t:\n            break\n        last_point.slope += d_slope\n        last_point.ts = t_i\n\n    if last_point.bias < 0:\n        last_point.bias = 0\n    return convert(last_point.bias, uint256)\n\n\n@external\n@view\ndef totalSupply(t: uint256 = block.timestamp) -> uint256:\n    \"\"\"\n    @notice Calculate total voting power\n    @dev Adheres to the ERC20 `totalSupply` interface for Aragon compatibility\n    @return Total voting power\n    \"\"\"\n    _epoch: uint256 = self.epoch\n    last_point: Point = self.point_history[_epoch]\n    return self.supply_at(last_point, t)\n\n\n@external\n@view\ndef totalSupplyAt(_block: uint256) -> uint256:\n    \"\"\"\n    @notice Calculate total voting power at some point in the past\n    @param _block Block to calculate the total voting power at\n    @return Total voting power at `_block`\n    \"\"\"\n    assert _block <= block.number\n    _epoch: uint256 = self.epoch\n    target_epoch: uint256 = self.find_block_epoch(_block, _epoch)\n\n    point: Point = self.point_history[target_epoch]\n    dt: uint256 = 0\n    if target_epoch < _epoch:\n        point_next: Point = self.point_history[target_epoch + 1]\n        if point.blk != point_next.blk:\n            dt = (_block - point.blk) * (point_next.ts - point.ts) / (point_next.blk - point.blk)\n    else:\n        if point.blk != block.number:\n            dt = (_block - point.blk) * (block.timestamp - point.ts) / (block.number - point.blk)\n    # Now dt contains info on how far are we beyond point\n\n    return self.supply_at(point, point.ts + dt)\n\n\n# Dummy methods for compatibility with Aragon\n\n@external\ndef changeController(_newController: address):\n    \"\"\"\n    @dev Dummy method required for Aragon compatibility\n    \"\"\"\n    assert msg.sender == self.controller\n    self.controller = _newController","deployed_bytecode":"0x600436101561000d5761323c565b600035601c52740100000000000000000000000000000000000000006020526f7fffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff8000000000000000000000000000000060605274012a05f1fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffed5fa0e000000000000000000000000000000000060a052636b441a4060005114156101105734156100ba57600080fd5b60043560205181106100cb57600080fd5b5060105433146100da57600080fd5b600435601155600435610140527f2f56810a6bf40af059b96d3aea4db54081f378029a518390491093a7b67032e96020610140a1005b636a1c05ae600051141561018657341561012957600080fd5b601054331461013757600080fd5b601154610140526000610140511861014e57600080fd5b6101405160105561014051610160527febee2d5739011062cb4f14113f3b36bf0ffe3da5c0568f64189d1012a11891056020610160a1005b6357f901e260005114156101c757341561019f57600080fd5b60043560205181106101b057600080fd5b5060105433146101bf57600080fd5b600435600e55005b638e5b490f60005114156101f65734156101e057600080fd5b60105433146101ee57600080fd5b600e54600f55005b6000156102e7575b6101605261014052326101405118156102e157600f54610180526000610180511815610270576020610220602463c23697a86101a052610140516101c0526101bc6000610180515af161025057600080fd5b601f3d1161025d57600080fd5b600050610220511561026f5761016051565b5b6308c379a06102605260206102805260256102a0527f536d61727420636f6e7472616374206465706f7369746f7273206e6f7420616c6102c0527f6c6f7765640000000000000000000000000000000000000000000000000000006102e0526102a05060006102e057608461027cfd5b5b61016051565b637c74a174600051141561036b57341561030057600080fd5b600435602051811061031157600080fd5b50600660043560e05260c052604060c0205461014052600161014051633b9aca00811061033d57600080fd5b600560043560e05260c052604060c02060c052602060c0200160c052602060c020015460005260206000f350005b63da020a1860005114156103d957341561038457600080fd5b600435602051811061039557600080fd5b506002602435633b9aca0081106103ab57600080fd5b600560043560e05260c052604060c02060c052602060c0200160c052602060c020015460005260206000f350005b63adc63589600051141561042b5734156103f257600080fd5b600435602051811061040357600080fd5b506001600260043560e05260c052604060c02060c052602060c020015460005260206000f350005b600015610d33575b6101e0526101405261016052610180526101a0526101c052608036610200376080366102803760006103005260006103205260035461034052600061014051181561063c574261018051111561048f5760006101605113610492565b60005b1561052f5761016051630784ce0060605181806104ae57600080fd5b8305806040519013156104c057600080fd5b80919012156104ce57600080fd5b9050905061022052610220516101805142808210156104ec57600080fd5b8082039050905060405181111561050257600080fd5b6060518183028060405190131561051857600080fd5b809190121561052657600080fd5b90509050610200525b426101c05111156105465760006101a05113610549565b60005b156105e6576101a051630784ce00606051818061056557600080fd5b83058060405190131561057757600080fd5b809190121561058557600080fd5b905090506102a0526102a0516101c05142808210156105a357600080fd5b808203905090506040518111156105b957600080fd5b606051818302806040519013156105cf57600080fd5b80919012156105dd57600080fd5b90509050610280525b60076101805160e05260c052604060c020546103005260006101c051181561063b57610180516101c051141561062357610300516103205261063a565b60076101c05160e05260c052604060c02054610320525b5b5b61036060008152600081602001524281604001524381606001525060006103405111156106d357610360610340516c01431e0fae6d7217caa0000000811061068357600080fd5b600460c052602060c020018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015260038160c052602060c0200154826060015250505b6103a0516103e0526104006103608051825280602001518260200152806040015182604001528060600151826060015250506000610480526103a05142111561078257670de0b6b3a7640000436103c0518082101561073157600080fd5b80820390509050808202821582848304141761074c57600080fd5b80905090509050426103a0518082101561076557600080fd5b80820390509050808061077757600080fd5b820490509050610480525b6103e05162093a80808061079557600080fd5b82049050905062093a8080820282158284830414176107b357600080fd5b809050905090506104a0526104c0600060ff818352015b6104a0805162093a808181830110156107e257600080fd5b8082019050905081525060006104e052426104a051111561080757426104a05261081e565b60076104a05160e05260c052604060c020546104e0525b6103608051610380516104a0516103e0518082101561083c57600080fd5b8082039050905060405181111561085257600080fd5b6060518183028060405190131561086857600080fd5b809190121561087657600080fd5b905090506060518183038060405190131561089057600080fd5b809190121561089e57600080fd5b9050905081525061038080516104e051606051818301806040519013156108c457600080fd5b80919012156108d257600080fd5b9050905081525060006103605112156108ec576000610360525b60006103805112156108ff576000610380525b6104a0516103e0526104a0516103a05261046051610480516104a051610440518082101561092c57600080fd5b80820390509050808202821582848304141761094757600080fd5b80905090509050670de0b6b3a7640000808061096257600080fd5b82049050905081818301101561097757600080fd5b808201905090506103c0526103408051600181818301101561099857600080fd5b80820190509050815250426104a05114156109bb57436103c052610a2456610a13565b610340516c01431e0fae6d7217caa000000081106109d857600080fd5b600460c052602060c0200160c052602060c0206103608051825580602001516001830155806040015160028301558060600151600383015550505b5b81516001018083528114156107ca575b5050610340516003556000610140511815610b205761038080516102a0516102205160605181830380604051901315610a5c57600080fd5b8091901215610a6a57600080fd5b9050905060605181830180604051901315610a8457600080fd5b8091901215610a9257600080fd5b905090508152506103608051610280516102005160605181830380604051901315610abc57600080fd5b8091901215610aca57600080fd5b9050905060605181830180604051901315610ae457600080fd5b8091901215610af257600080fd5b905090508152506000610380511215610b0c576000610380525b6000610360511215610b1f576000610360525b5b610340516c01431e0fae6d7217caa00000008110610b3d57600080fd5b600460c052602060c0200160c052602060c0206103608051825580602001516001830155806040015160028301558060600151600383015550506000610140511815610d2d5742610180511115610c1c5761030080516102205160605181830180604051901315610bad57600080fd5b8091901215610bbb57600080fd5b90509050815250610180516101c0511415610c055761030080516102a05160605181830380604051901315610bef57600080fd5b8091901215610bfd57600080fd5b905090508152505b6103005160076101805160e05260c052604060c020555b426101c0511115610c8157610180516101c0511115610c805761032080516102a05160605181830380604051901315610c5457600080fd5b8091901215610c6257600080fd5b905090508152506103205160076101c05160e05260c052604060c020555b5b60066101405160e05260c052604060c020546001818183011015610ca457600080fd5b80820190509050610500526105005160066101405160e05260c052604060c02055426102c052436102e05261050051633b9aca008110610ce357600080fd5b60056101405160e05260c052604060c02060c052602060c0200160c052602060c0206102808051825580602001516001830155806040015160028301558060600151600383015550505b6101e051565b600015610fd5575b610200526101405261016052610180526101a0526101c0526101e0526102206101a080518252806020015182602001525050600154610260526102605161016051818183011015610d8b57600080fd5b8082019050905060015561028061022080518252806020015182602001525050610220805161016051604051811115610dc357600080fd5b60605181830180604051901315610dd957600080fd5b8091901215610de757600080fd5b905090508152506000610180511815610e035761018051610240525b60026101405160e05260c052604060c02060c052602060c020610220805182558060200151600183015550506101406102c0525b6102c0515160206102c051016102c0526102c06102c0511015610e5957610e37565b610140516102e0526103006102808051825280602001518260200152505061034061022080518252806020015182602001525050610360516103405161032051610300516102e05160065801610433565b6102a06102c0525b6102c0515260206102c051036102c0526101406102c051101515610ed557610eb2565b6000506000610160511815610f3a57602061048060646323b872dd6103c052610140516103e052306104005261016051610420526103dc60006000545af1610f1c57600080fd5b601f3d11610f2957600080fd5b60005061048051610f3957600080fd5b5b610160516104a0526101e0516104c052426104e05261024051610140517f4566dfc29f6f11d13a418c26a02bef7c28bae749d4de47e4e6a7cddea6730d5960606104a0a361026051610500526102605161016051818183011015610f9d57600080fd5b80820190509050610520527f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c6040610500a161020051565b63c2c4c5c16000511415611024573415610fee57600080fd5b600061014052604036610160376040366101a0376101c0516101a05161018051610160516101405160065801610433565b600050005b633a46273e600051141561123a5762ffffff541561104157600080fd5b600162ffffff55341561105357600080fd5b600435602051811061106457600080fd5b50610140600260043560e05260c052604060c0208060c052602060c02054825260018160c052602060c0200154826020015250506000602435116110a757600080fd5b6308c379a06101805260206101a05260166101c0527f4e6f206578697374696e67206c6f636b20666f756e64000000000000000000006101e0526101c050600061014051136110f757606461019cfd5b6308c379a0610220526020610240526024610260527f43616e6e6f742061646420746f2065787069726564206c6f636b2e2057697468610280527f64726177000000000000000000000000000000000000000000000000000000006102a0526102605042610160511161116b57608461023cfd5b6101406102e0525b6102e0515160206102e051016102e0526102e06102e051101561119557611173565b6004356103005260243561032052600061034052610360600260043560e05260c052604060c0208060c052602060c02054825260018160c052602060c02001548260200152505060006103a0526103a051610380516103605161034051610320516103005160065801610d3b565b6102c06102e0525b6102e0515260206102e051036102e0526101406102e05110151561122e5761120b565b600050600062ffffff55005b6365fc387360005114156114d85762ffffff541561125757600080fd5b600162ffffff55341561126957600080fd5b336101405261014051600658016101fe565b60005060243562093a80808061129057600080fd5b82049050905062093a8080820282158284830414176112ae57600080fd5b809050905090506101a0526101c060023360e05260c052604060c0208060c052602060c02054825260018160c052602060c0200154826020015250506000600435116112f957600080fd5b6308c379a0610200526020610220526019610240527f5769746864726177206f6c6420746f6b656e732066697273740000000000000061026052610240506101c0511561134757606461021cfd5b6308c379a06102a05260206102c05260266102e0527f43616e206f6e6c79206c6f636b20756e74696c2074696d6520696e2074686520610300527f6675747572650000000000000000000000000000000000000000000000000000610320526102e050426101a051116113bb5760846102bcfd5b6308c379a061036052602061038052601e6103a0527f566f74696e67206c6f636b2063616e2062652034207965617273206d617800006103c0526103a05042630784ce0081818301101561140e57600080fd5b808201905090506101a051111561142657606461037cfd5b610140610400525b610400515160206104005101610400526104006104005110156114505761142e565b3361042052600435610440526101a051610460526104806101c08051825280602001518260200152505060016104c0526104c0516104a0516104805161046051610440516104205160065801610d3b565b6103e0610400525b61040051526020610400510361040052610140610400511015156114cc576114a9565b600050600062ffffff55005b634957677c60005114156116d05762ffffff54156114f557600080fd5b600162ffffff55341561150757600080fd5b336101405261014051600658016101fe565b6000506101a060023360e05260c052604060c0208060c052602060c02054825260018160c052602060c02001548260200152505060006004351161155c57600080fd5b6308c379a06101e0526020610200526016610220527f4e6f206578697374696e67206c6f636b20666f756e6400000000000000000000610240526102205060006101a051136115ac5760646101fcfd5b6308c379a06102805260206102a05260246102c0527f43616e6e6f742061646420746f2065787069726564206c6f636b2e20576974686102e0527f6472617700000000000000000000000000000000000000000000000000000000610300526102c050426101c0511161162057608461029cfd5b610140610340525b6103405151602061034051016103405261034061034051101561164a57611628565b33610360526004356103805260006103a0526103c06101a080518252806020015182602001525050600261040052610400516103e0516103c0516103a051610380516103605160065801610d3b565b610320610340525b61034051526020610340510361034052610140610340511015156116c4576116a1565b600050600062ffffff55005b63eff7a612600051141561198d5762ffffff54156116ed57600080fd5b600162ffffff5534156116ff57600080fd5b336101405261014051600658016101fe565b6000506101a060023360e05260c052604060c0208060c052602060c02054825260018160c052602060c02001548260200152505060043562093a80808061175757600080fd5b82049050905062093a80808202821582848304141761177557600080fd5b809050905090506101e0526308c379a061020052602061022052600c610240527f4c6f636b206578706972656400000000000000000000000000000000000000006102605261024050426101c051116117cf57606461021cfd5b6308c379a06102a05260206102c05260116102e0527f4e6f7468696e67206973206c6f636b6564000000000000000000000000000000610300526102e05060006101a0511361181f5760646102bcfd5b6308c379a061034052602061036052601f610380527f43616e206f6e6c7920696e637265617365206c6f636b206475726174696f6e006103a052610380506101c0516101e0511161187157606461035cfd5b6308c379a06103e052602061040052601e610420527f566f74696e67206c6f636b2063616e2062652034207965617273206d61780000610440526104205042630784ce008181830110156118c457600080fd5b808201905090506101e05111156118dc5760646103fcfd5b610140610480525b61048051516020610480510161048052610480610480511015611906576118e4565b336104a05260006104c0526101e0516104e0526105006101a0805182528060200151826020015250506003610540526105405161052051610500516104e0516104c0516104a05160065801610d3b565b610460610480525b61048051526020610480510361048052610140610480511015156119815761195e565b600050600062ffffff55005b633ccfd60b6000511415611c445762ffffff54156119aa57600080fd5b600162ffffff5534156119bc57600080fd5b61014060023360e05260c052604060c0208060c052602060c02054825260018160c052602060c0200154826020015250506308c379a06101805260206101a05260166101c0527f546865206c6f636b206469646e277420657870697265000000000000000000006101e0526101c05061016051421015611a3d57606461019cfd5b610140516000811215611a4f57600080fd5b610220526102406101408051825280602001518260200152505060006101605260006101405260023360e05260c052604060c02060c052602060c0206101408051825580602001516001830155505060015461028052610280516102205180821015611aba57600080fd5b808203905090506001556101406102a0525b6102a0515160206102a051016102a0526102a06102a0511015611aee57611acc565b336102c0526102e061024080518252806020015182602001525050610320610140805182528060200151826020015250506103405161032051610300516102e0516102c05160065801610433565b6102806102a0525b6102a0515260206102a051036102a0526101406102a051101515611b6757611b44565b6000506020610440604463a9059cbb6103a052336103c052610220516103e0526103bc60006000545af1611b9a57600080fd5b601f3d11611ba757600080fd5b60005061044051611bb757600080fd5b61022051610460524261048052337ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5686040610460a2610280516104a052610280516102205180821015611c0957600080fd5b808203905090506104c0527f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c60406104a0a1600062ffffff55005b600015611d63575b61018052610140526101605260006101a052610160516101c0526101e060006080818352015b6101c0516101a051101515611c8657611d4f565b6101a0516101c051818183011015611c9d57600080fd5b808201905090506001818183011015611cb557600080fd5b8082019050905060028080611cc957600080fd5b82049050905061020052610140516003610200516c01431e0fae6d7217caa00000008110611cf657600080fd5b600460c052602060c0200160c052602060c0200154111515611d1f57610200516101a052611d3e565b61020051600180821015611d3257600080fd5b808203905090506101c0525b5b8151600101808352811415611c72575b50506101a051600052600051610180515650005b6370a082316000511415611d7b574261014052611da0565b62fdd58e6000511415611d98576020602461014037600050611da0565b600015611f18575b3415611dab57600080fd5b6004356020518110611dbc57600080fd5b50600660043560e05260c052604060c0205461016052610160511515611dec57600060005260206000f350611f16565b61018061016051633b9aca008110611e0357600080fd5b600560043560e05260c052604060c02060c052602060c020018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015260038160c052602060c02001548260600152505061018080516101a051610140516101c05180821015611e7e57600080fd5b80820390509050604051811115611e9457600080fd5b60605181830280604051901315611eaa57600080fd5b8091901215611eb857600080fd5b9050905060605181830380604051901315611ed257600080fd5b8091901215611ee057600080fd5b905090508152506000610180511215611efa576000610180525b610180516000811215611f0c57600080fd5b60005260206000f3505b005b634ee2cd7e6000511415612427573415611f3157600080fd5b6004356020518110611f4257600080fd5b50436024351115611f5257600080fd5b600061014052600660043560e05260c052604060c020546101605261018060006080818352015b6101605161014051101515611f8d5761205a565b6101405161016051818183011015611fa457600080fd5b808201905090506001818183011015611fbc57600080fd5b8082019050905060028080611fd057600080fd5b8204905090506101a05260243560036101a051633b9aca008110611ff357600080fd5b600560043560e05260c052604060c02060c052602060c0200160c052602060c020015411151561202a576101a05161014052612049565b6101a05160018082101561203d57600080fd5b80820390509050610160525b5b8151600101808352811415611f79575b50506101c061014051633b9aca00811061207357600080fd5b600560043560e05260c052604060c02060c052602060c020018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015260038160c052602060c020015482606001525050600354610240526101405161016051610180516101a0516101c0516101e051610200516102205161024051610260516024356102a052610240516102c0526102c0516102a05160065801611c4c565b61032052610260526102405261022052610200526101e0526101c0526101a0526101805261016052610140526103205161026052610340610260516c01431e0fae6d7217caa0000000811061217357600080fd5b600460c052602060c020018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015260038160c052602060c02001548260600152505060006103c05260006103e052610240516102605110156122a8576104006102605160018181830110156121f457600080fd5b808201905090506c01431e0fae6d7217caa0000000811061221457600080fd5b600460c052602060c020018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015260038160c052602060c020015482606001525050610460516103a0518082101561227857600080fd5b808203905090506103c05261044051610380518082101561229857600080fd5b808203905090506103e0526122e3565b436103a051808210156122ba57600080fd5b808203905090506103c0524261038051808210156122d757600080fd5b808203905090506103e0525b610380516104805260006103c05118156123655761048080516103e0516024356103a0518082101561231457600080fd5b80820390509050808202821582848304141761232f57600080fd5b809050905090506103c051808061234557600080fd5b82049050905081818301101561235a57600080fd5b808201905090508152505b6101c080516101e05161048051610200518082101561238357600080fd5b8082039050905060405181111561239957600080fd5b606051818302806040519013156123af57600080fd5b80919012156123bd57600080fd5b90509050606051818303806040519013156123d757600080fd5b80919012156123e557600080fd5b9050905081525060006101c051121515612419576101c051600081121561240b57600080fd5b60005260206000f350612425565b600060005260206000f3505b005b60001561262f575b6101e0526101405261016052610180526101a0526101c0526102006101408051825280602001518260200152806040015182604001528060600151826060015250506102405162093a80808061248457600080fd5b82049050905062093a8080820282158284830414176124a257600080fd5b80905090509050610280526102a0600060ff818352015b610280805162093a808181830110156124d157600080fd5b8082019050905081525060006102c0526101c0516102805111156124fc576101c05161028052612513565b60076102805160e05260c052604060c020546102c0525b61020080516102205161028051610240518082101561253157600080fd5b8082039050905060405181111561254757600080fd5b6060518183028060405190131561255d57600080fd5b809190121561256b57600080fd5b905090506060518183038060405190131561258557600080fd5b809190121561259357600080fd5b905090508152506101c0516102805114156125ad576125fa565b61022080516102c051606051818301806040519013156125cc57600080fd5b80919012156125da57600080fd5b9050905081525061028051610240525b81516001018083528114156124b9575b5050600061020051121561260f576000610200525b61020051600081121561262157600080fd5b6000526000516101e0515650005b6318160ddd600051141561264757426101405261266d565b63bd85b039600051141561266557602060046101403760005061266d565b600015612780575b341561267857600080fd5b60035461016052610180610160516c01431e0fae6d7217caa0000000811061269f57600080fd5b600460c052602060c020018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015260038160c052602060c0200154826060015250506101405161016051610180516101a0516101c0516101e051610220610180805182528060200151826020015280604001518260400152806060015182606001525050610140516102a0526102a051610280516102605161024051610220516006580161242f565b610300526101e0526101c0526101a0526101805261016052610140526103005160005260206000f350005b63981b24d06000511415612ae757341561279957600080fd5b4360043511156127a857600080fd5b6003546101405261014051610160516004356101a052610140516101c0526101c0516101a05160065801611c4c565b6102205261016052610140526102205161016052610240610160516c01431e0fae6d7217caa0000000811061280b57600080fd5b600460c052602060c020018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015260038160c052602060c02001548260600152505060006102c0526101405161016051101561298c576102e061016051600181818301101561288657600080fd5b808201905090506c01431e0fae6d7217caa000000081106128a657600080fd5b600460c052602060c020018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015260038160c052602060c020015482606001525050610340516102a0511815612987576004356102a0518082101561291757600080fd5b8082039050905061032051610280518082101561293357600080fd5b80820390509050808202821582848304141761294e57600080fd5b80905090509050610340516102a0518082101561296a57600080fd5b80820390509050808061297c57600080fd5b8204905090506102c0525b612a16565b436102a0511815612a15576004356102a051808210156129ab57600080fd5b808203905090504261028051808210156129c457600080fd5b8082039050905080820282158284830414176129df57600080fd5b80905090509050436102a051808210156129f857600080fd5b808203905090508080612a0a57600080fd5b8204905090506102c0525b5b610140610360525b610360515160206103605101610360526102e0610360511015612a4057612a1e565b610380610240805182528060200151826020015280604001518260400152806060015182606001525050610280516102c051818183011015612a8157600080fd5b8082019050905061040052610400516103e0516103c0516103a051610380516006580161242f565b610460526102c0610360525b6103605152602061036051036103605261014061036051101515612ad857612ab5565b6104605160005260206000f350005b633cebb8236000511415612b28573415612b0057600080fd5b6004356020518110612b1157600080fd5b506008543314612b2057600080fd5b600435600855005b63fc0c546a6000511415612b4f573415612b4157600080fd5b60005460005260206000f350005b63047fc9aa6000511415612b76573415612b6857600080fd5b60015460005260206000f350005b63cbf9fe5f6000511415612bff573415612b8f57600080fd5b6004356020518110612ba057600080fd5b50610140808080600260043560e05260c052604060c02060c052602060c020548152505060208101905080806001600260043560e05260c052604060c02060c052602060c02001548152505060409050905060c05260c051610140f350005b63900cf0cf6000511415612c26573415612c1857600080fd5b60035460005260206000f350005b63d1febfb96000511415612d49573415612c3f57600080fd5b6101408080806004356c01431e0fae6d7217caa00000008110612c6157600080fd5b600460c052602060c0200160c052602060c0205481525050602081019050808060016004356c01431e0fae6d7217caa00000008110612c9f57600080fd5b600460c052602060c0200160c052602060c020015481525050602081019050808060026004356c01431e0fae6d7217caa00000008110612cde57600080fd5b600460c052602060c0200160c052602060c020015481525050602081019050808060036004356c01431e0fae6d7217caa00000008110612d1d57600080fd5b600460c052602060c0200160c052602060c02001548152505060809050905060c05260c051610140f350005b6328d09d476000511415612e92573415612d6257600080fd5b6004356020518110612d7357600080fd5b50610140808080602435633b9aca008110612d8d57600080fd5b600560043560e05260c052604060c02060c052602060c0200160c052602060c020548152505060208101905080806001602435633b9aca008110612dd057600080fd5b600560043560e05260c052604060c02060c052602060c0200160c052602060c02001548152505060208101905080806002602435633b9aca008110612e1457600080fd5b600560043560e05260c052604060c02060c052602060c0200160c052602060c02001548152505060208101905080806003602435633b9aca008110612e5857600080fd5b600560043560e05260c052604060c02060c052602060c0200160c052602060c02001548152505060809050905060c05260c051610140f350005b63010ae7576000511415612ed9573415612eab57600080fd5b6004356020518110612ebc57600080fd5b50600660043560e05260c052604060c0205460005260206000f350005b63711974846000511415612f0e573415612ef257600080fd5b600760043560e05260c052604060c0205460005260206000f350005b63f77c47916000511415612f35573415612f2757600080fd5b60085460005260206000f350005b63bef97c876000511415612f5c573415612f4e57600080fd5b60095460005260206000f350005b6306fdde036000511415613010573415612f7557600080fd5b600a8060c052602060c020610180602082540161012060006003818352015b82610120516020021115612fa757612fc9565b61012051850154610120516020028501525b8151600101808352811415612f94575b50505050505061018051806101a001818260206001820306601f82010390500336823750506020610160526040610180510160206001820306601f8201039050610160f350005b6395d89b4160005114156130c457341561302957600080fd5b600b8060c052602060c020610180602082540161012060006002818352015b8261012051602002111561305b5761307d565b61012051850154610120516020028501525b8151600101808352811415613048575b50505050505061018051806101a001818260206001820306601f82010390500336823750506020610160526040610180510160206001820306601f8201039050610160f350005b6354fd4d5060005114156131785734156130dd57600080fd5b600c8060c052602060c020610180602082540161012060006002818352015b8261012051602002111561310f57613131565b61012051850154610120516020028501525b81516001018083528114156130fc575b50505050505061018051806101a001818260206001820306601f82010390500336823750506020610160526040610180510160206001820306601f8201039050610160f350005b63313ce567600051141561319f57341561319157600080fd5b600d5460005260206000f350005b638ff36fd160005114156131c65734156131b857600080fd5b600e5460005260206000f350005b637175d4f760005114156131ed5734156131df57600080fd5b600f5460005260206000f350005b63f851a440600051141561321457341561320657600080fd5b60105460005260206000f350005b6317f7182a600051141561323b57341561322d57600080fd5b60115460005260206000f350005b5b60006000fd","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"libraries":{},"outputSelection":{"Vyper_contract.vy":["abi","ast","interface","ir","userdoc","devdoc","evm.bytecode.object","evm.bytecode.opcodes","evm.deployedBytecode.object","evm.deployedBytecode.opcodes","evm.deployedBytecode.sourceMap","evm.methodIdentifiers"]},"search_paths":["."]},"optimization_runs":null,"sourcify_repo_url":null,"decoded_constructor_args":[["0xD533a949740bb3306d119CC777fa900bA034cd52",{"name":"token_addr","type":"address"}],["Vote-escrowed CRV",{"name":"_name","type":"string"}],["veCRV",{"name":"_symbol","type":"string"}],["veCRV_1.0.0",{"name":"_version","type":"string"}]],"compiler_version":"0.2.4+commit.7949850","is_verified_via_verifier_alliance":true,"verified_at":"2025-05-09T10:03:13.989802Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x740100000000000000000000000000000000000000006020526f7fffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff8000000000000000000000000000000060605274012a05f1fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffed5fa0e000000000000000000000000000000000060a05260806135616101403934156100a157600080fd5b602061356160c03960c05160205181106100ba57600080fd5b506060602060206135610160c03960c051613561016101c0396040602060206135610160c03960c0516004013511156100f257600080fd5b6040602060406135610160c03960c05161356101610240396020602060406135610160c03960c05160040135111561012957600080fd5b6040602060606135610160c03960c051613561016102a0396020602060606135610160c03960c05160040135111561016057600080fd5b3360105561014051600055436003600460c052602060c02060c052602060c0200155426002600460c052602060c02060c052602060c02001553360085560016009556020610380600463313ce5676103205261033c610140515afa6101c457600080fd5b601f3d116101d157600080fd5b600050610380516103005260ff6103005111156101ed57600080fd5b61030051600d556101c080600a60c052602060c020602082510161012060006003818352015b8261012051602002111561022657610248565b61012051602002850151610120518501555b8151600101808352811415610213575b50505050505061024080600b60c052602060c020602082510161012060006002818352015b82610120516020021115610280576102a2565b61012051602002850151610120518501555b815160010180835281141561026d575b5050505050506102a080600c60c052602060c020602082510161012060006002818352015b826101205160200211156102da576102fc565b61012051602002850151610120518501555b81516001018083528114156102c7575b50505050505061354956600436101561000d5761323c565b600035601c52740100000000000000000000000000000000000000006020526f7fffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff8000000000000000000000000000000060605274012a05f1fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffed5fa0e000000000000000000000000000000000060a052636b441a4060005114156101105734156100ba57600080fd5b60043560205181106100cb57600080fd5b5060105433146100da57600080fd5b600435601155600435610140527f2f56810a6bf40af059b96d3aea4db54081f378029a518390491093a7b67032e96020610140a1005b636a1c05ae600051141561018657341561012957600080fd5b601054331461013757600080fd5b601154610140526000610140511861014e57600080fd5b6101405160105561014051610160527febee2d5739011062cb4f14113f3b36bf0ffe3da5c0568f64189d1012a11891056020610160a1005b6357f901e260005114156101c757341561019f57600080fd5b60043560205181106101b057600080fd5b5060105433146101bf57600080fd5b600435600e55005b638e5b490f60005114156101f65734156101e057600080fd5b60105433146101ee57600080fd5b600e54600f55005b6000156102e7575b6101605261014052326101405118156102e157600f54610180526000610180511815610270576020610220602463c23697a86101a052610140516101c0526101bc6000610180515af161025057600080fd5b601f3d1161025d57600080fd5b600050610220511561026f5761016051565b5b6308c379a06102605260206102805260256102a0527f536d61727420636f6e7472616374206465706f7369746f7273206e6f7420616c6102c0527f6c6f7765640000000000000000000000000000000000000000000000000000006102e0526102a05060006102e057608461027cfd5b5b61016051565b637c74a174600051141561036b57341561030057600080fd5b600435602051811061031157600080fd5b50600660043560e05260c052604060c0205461014052600161014051633b9aca00811061033d57600080fd5b600560043560e05260c052604060c02060c052602060c0200160c052602060c020015460005260206000f350005b63da020a1860005114156103d957341561038457600080fd5b600435602051811061039557600080fd5b506002602435633b9aca0081106103ab57600080fd5b600560043560e05260c052604060c02060c052602060c0200160c052602060c020015460005260206000f350005b63adc63589600051141561042b5734156103f257600080fd5b600435602051811061040357600080fd5b506001600260043560e05260c052604060c02060c052602060c020015460005260206000f350005b600015610d33575b6101e0526101405261016052610180526101a0526101c052608036610200376080366102803760006103005260006103205260035461034052600061014051181561063c574261018051111561048f5760006101605113610492565b60005b1561052f5761016051630784ce0060605181806104ae57600080fd5b8305806040519013156104c057600080fd5b80919012156104ce57600080fd5b9050905061022052610220516101805142808210156104ec57600080fd5b8082039050905060405181111561050257600080fd5b6060518183028060405190131561051857600080fd5b809190121561052657600080fd5b90509050610200525b426101c05111156105465760006101a05113610549565b60005b156105e6576101a051630784ce00606051818061056557600080fd5b83058060405190131561057757600080fd5b809190121561058557600080fd5b905090506102a0526102a0516101c05142808210156105a357600080fd5b808203905090506040518111156105b957600080fd5b606051818302806040519013156105cf57600080fd5b80919012156105dd57600080fd5b90509050610280525b60076101805160e05260c052604060c020546103005260006101c051181561063b57610180516101c051141561062357610300516103205261063a565b60076101c05160e05260c052604060c02054610320525b5b5b61036060008152600081602001524281604001524381606001525060006103405111156106d357610360610340516c01431e0fae6d7217caa0000000811061068357600080fd5b600460c052602060c020018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015260038160c052602060c0200154826060015250505b6103a0516103e0526104006103608051825280602001518260200152806040015182604001528060600151826060015250506000610480526103a05142111561078257670de0b6b3a7640000436103c0518082101561073157600080fd5b80820390509050808202821582848304141761074c57600080fd5b80905090509050426103a0518082101561076557600080fd5b80820390509050808061077757600080fd5b820490509050610480525b6103e05162093a80808061079557600080fd5b82049050905062093a8080820282158284830414176107b357600080fd5b809050905090506104a0526104c0600060ff818352015b6104a0805162093a808181830110156107e257600080fd5b8082019050905081525060006104e052426104a051111561080757426104a05261081e565b60076104a05160e05260c052604060c020546104e0525b6103608051610380516104a0516103e0518082101561083c57600080fd5b8082039050905060405181111561085257600080fd5b6060518183028060405190131561086857600080fd5b809190121561087657600080fd5b905090506060518183038060405190131561089057600080fd5b809190121561089e57600080fd5b9050905081525061038080516104e051606051818301806040519013156108c457600080fd5b80919012156108d257600080fd5b9050905081525060006103605112156108ec576000610360525b60006103805112156108ff576000610380525b6104a0516103e0526104a0516103a05261046051610480516104a051610440518082101561092c57600080fd5b80820390509050808202821582848304141761094757600080fd5b80905090509050670de0b6b3a7640000808061096257600080fd5b82049050905081818301101561097757600080fd5b808201905090506103c0526103408051600181818301101561099857600080fd5b80820190509050815250426104a05114156109bb57436103c052610a2456610a13565b610340516c01431e0fae6d7217caa000000081106109d857600080fd5b600460c052602060c0200160c052602060c0206103608051825580602001516001830155806040015160028301558060600151600383015550505b5b81516001018083528114156107ca575b5050610340516003556000610140511815610b205761038080516102a0516102205160605181830380604051901315610a5c57600080fd5b8091901215610a6a57600080fd5b9050905060605181830180604051901315610a8457600080fd5b8091901215610a9257600080fd5b905090508152506103608051610280516102005160605181830380604051901315610abc57600080fd5b8091901215610aca57600080fd5b9050905060605181830180604051901315610ae457600080fd5b8091901215610af257600080fd5b905090508152506000610380511215610b0c576000610380525b6000610360511215610b1f576000610360525b5b610340516c01431e0fae6d7217caa00000008110610b3d57600080fd5b600460c052602060c0200160c052602060c0206103608051825580602001516001830155806040015160028301558060600151600383015550506000610140511815610d2d5742610180511115610c1c5761030080516102205160605181830180604051901315610bad57600080fd5b8091901215610bbb57600080fd5b90509050815250610180516101c0511415610c055761030080516102a05160605181830380604051901315610bef57600080fd5b8091901215610bfd57600080fd5b905090508152505b6103005160076101805160e05260c052604060c020555b426101c0511115610c8157610180516101c0511115610c805761032080516102a05160605181830380604051901315610c5457600080fd5b8091901215610c6257600080fd5b905090508152506103205160076101c05160e05260c052604060c020555b5b60066101405160e05260c052604060c020546001818183011015610ca457600080fd5b80820190509050610500526105005160066101405160e05260c052604060c02055426102c052436102e05261050051633b9aca008110610ce357600080fd5b60056101405160e05260c052604060c02060c052602060c0200160c052602060c0206102808051825580602001516001830155806040015160028301558060600151600383015550505b6101e051565b600015610fd5575b610200526101405261016052610180526101a0526101c0526101e0526102206101a080518252806020015182602001525050600154610260526102605161016051818183011015610d8b57600080fd5b8082019050905060015561028061022080518252806020015182602001525050610220805161016051604051811115610dc357600080fd5b60605181830180604051901315610dd957600080fd5b8091901215610de757600080fd5b905090508152506000610180511815610e035761018051610240525b60026101405160e05260c052604060c02060c052602060c020610220805182558060200151600183015550506101406102c0525b6102c0515160206102c051016102c0526102c06102c0511015610e5957610e37565b610140516102e0526103006102808051825280602001518260200152505061034061022080518252806020015182602001525050610360516103405161032051610300516102e05160065801610433565b6102a06102c0525b6102c0515260206102c051036102c0526101406102c051101515610ed557610eb2565b6000506000610160511815610f3a57602061048060646323b872dd6103c052610140516103e052306104005261016051610420526103dc60006000545af1610f1c57600080fd5b601f3d11610f2957600080fd5b60005061048051610f3957600080fd5b5b610160516104a0526101e0516104c052426104e05261024051610140517f4566dfc29f6f11d13a418c26a02bef7c28bae749d4de47e4e6a7cddea6730d5960606104a0a361026051610500526102605161016051818183011015610f9d57600080fd5b80820190509050610520527f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c6040610500a161020051565b63c2c4c5c16000511415611024573415610fee57600080fd5b600061014052604036610160376040366101a0376101c0516101a05161018051610160516101405160065801610433565b600050005b633a46273e600051141561123a5762ffffff541561104157600080fd5b600162ffffff55341561105357600080fd5b600435602051811061106457600080fd5b50610140600260043560e05260c052604060c0208060c052602060c02054825260018160c052602060c0200154826020015250506000602435116110a757600080fd5b6308c379a06101805260206101a05260166101c0527f4e6f206578697374696e67206c6f636b20666f756e64000000000000000000006101e0526101c050600061014051136110f757606461019cfd5b6308c379a0610220526020610240526024610260527f43616e6e6f742061646420746f2065787069726564206c6f636b2e2057697468610280527f64726177000000000000000000000000000000000000000000000000000000006102a0526102605042610160511161116b57608461023cfd5b6101406102e0525b6102e0515160206102e051016102e0526102e06102e051101561119557611173565b6004356103005260243561032052600061034052610360600260043560e05260c052604060c0208060c052602060c02054825260018160c052602060c02001548260200152505060006103a0526103a051610380516103605161034051610320516103005160065801610d3b565b6102c06102e0525b6102e0515260206102e051036102e0526101406102e05110151561122e5761120b565b600050600062ffffff55005b6365fc387360005114156114d85762ffffff541561125757600080fd5b600162ffffff55341561126957600080fd5b336101405261014051600658016101fe565b60005060243562093a80808061129057600080fd5b82049050905062093a8080820282158284830414176112ae57600080fd5b809050905090506101a0526101c060023360e05260c052604060c0208060c052602060c02054825260018160c052602060c0200154826020015250506000600435116112f957600080fd5b6308c379a0610200526020610220526019610240527f5769746864726177206f6c6420746f6b656e732066697273740000000000000061026052610240506101c0511561134757606461021cfd5b6308c379a06102a05260206102c05260266102e0527f43616e206f6e6c79206c6f636b20756e74696c2074696d6520696e2074686520610300527f6675747572650000000000000000000000000000000000000000000000000000610320526102e050426101a051116113bb5760846102bcfd5b6308c379a061036052602061038052601e6103a0527f566f74696e67206c6f636b2063616e2062652034207965617273206d617800006103c0526103a05042630784ce0081818301101561140e57600080fd5b808201905090506101a051111561142657606461037cfd5b610140610400525b610400515160206104005101610400526104006104005110156114505761142e565b3361042052600435610440526101a051610460526104806101c08051825280602001518260200152505060016104c0526104c0516104a0516104805161046051610440516104205160065801610d3b565b6103e0610400525b61040051526020610400510361040052610140610400511015156114cc576114a9565b600050600062ffffff55005b634957677c60005114156116d05762ffffff54156114f557600080fd5b600162ffffff55341561150757600080fd5b336101405261014051600658016101fe565b6000506101a060023360e05260c052604060c0208060c052602060c02054825260018160c052602060c02001548260200152505060006004351161155c57600080fd5b6308c379a06101e0526020610200526016610220527f4e6f206578697374696e67206c6f636b20666f756e6400000000000000000000610240526102205060006101a051136115ac5760646101fcfd5b6308c379a06102805260206102a05260246102c0527f43616e6e6f742061646420746f2065787069726564206c6f636b2e20576974686102e0527f6472617700000000000000000000000000000000000000000000000000000000610300526102c050426101c0511161162057608461029cfd5b610140610340525b6103405151602061034051016103405261034061034051101561164a57611628565b33610360526004356103805260006103a0526103c06101a080518252806020015182602001525050600261040052610400516103e0516103c0516103a051610380516103605160065801610d3b565b610320610340525b61034051526020610340510361034052610140610340511015156116c4576116a1565b600050600062ffffff55005b63eff7a612600051141561198d5762ffffff54156116ed57600080fd5b600162ffffff5534156116ff57600080fd5b336101405261014051600658016101fe565b6000506101a060023360e05260c052604060c0208060c052602060c02054825260018160c052602060c02001548260200152505060043562093a80808061175757600080fd5b82049050905062093a80808202821582848304141761177557600080fd5b809050905090506101e0526308c379a061020052602061022052600c610240527f4c6f636b206578706972656400000000000000000000000000000000000000006102605261024050426101c051116117cf57606461021cfd5b6308c379a06102a05260206102c05260116102e0527f4e6f7468696e67206973206c6f636b6564000000000000000000000000000000610300526102e05060006101a0511361181f5760646102bcfd5b6308c379a061034052602061036052601f610380527f43616e206f6e6c7920696e637265617365206c6f636b206475726174696f6e006103a052610380506101c0516101e0511161187157606461035cfd5b6308c379a06103e052602061040052601e610420527f566f74696e67206c6f636b2063616e2062652034207965617273206d61780000610440526104205042630784ce008181830110156118c457600080fd5b808201905090506101e05111156118dc5760646103fcfd5b610140610480525b61048051516020610480510161048052610480610480511015611906576118e4565b336104a05260006104c0526101e0516104e0526105006101a0805182528060200151826020015250506003610540526105405161052051610500516104e0516104c0516104a05160065801610d3b565b610460610480525b61048051526020610480510361048052610140610480511015156119815761195e565b600050600062ffffff55005b633ccfd60b6000511415611c445762ffffff54156119aa57600080fd5b600162ffffff5534156119bc57600080fd5b61014060023360e05260c052604060c0208060c052602060c02054825260018160c052602060c0200154826020015250506308c379a06101805260206101a05260166101c0527f546865206c6f636b206469646e277420657870697265000000000000000000006101e0526101c05061016051421015611a3d57606461019cfd5b610140516000811215611a4f57600080fd5b610220526102406101408051825280602001518260200152505060006101605260006101405260023360e05260c052604060c02060c052602060c0206101408051825580602001516001830155505060015461028052610280516102205180821015611aba57600080fd5b808203905090506001556101406102a0525b6102a0515160206102a051016102a0526102a06102a0511015611aee57611acc565b336102c0526102e061024080518252806020015182602001525050610320610140805182528060200151826020015250506103405161032051610300516102e0516102c05160065801610433565b6102806102a0525b6102a0515260206102a051036102a0526101406102a051101515611b6757611b44565b6000506020610440604463a9059cbb6103a052336103c052610220516103e0526103bc60006000545af1611b9a57600080fd5b601f3d11611ba757600080fd5b60005061044051611bb757600080fd5b61022051610460524261048052337ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5686040610460a2610280516104a052610280516102205180821015611c0957600080fd5b808203905090506104c0527f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c60406104a0a1600062ffffff55005b600015611d63575b61018052610140526101605260006101a052610160516101c0526101e060006080818352015b6101c0516101a051101515611c8657611d4f565b6101a0516101c051818183011015611c9d57600080fd5b808201905090506001818183011015611cb557600080fd5b8082019050905060028080611cc957600080fd5b82049050905061020052610140516003610200516c01431e0fae6d7217caa00000008110611cf657600080fd5b600460c052602060c0200160c052602060c0200154111515611d1f57610200516101a052611d3e565b61020051600180821015611d3257600080fd5b808203905090506101c0525b5b8151600101808352811415611c72575b50506101a051600052600051610180515650005b6370a082316000511415611d7b574261014052611da0565b62fdd58e6000511415611d98576020602461014037600050611da0565b600015611f18575b3415611dab57600080fd5b6004356020518110611dbc57600080fd5b50600660043560e05260c052604060c0205461016052610160511515611dec57600060005260206000f350611f16565b61018061016051633b9aca008110611e0357600080fd5b600560043560e05260c052604060c02060c052602060c020018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015260038160c052602060c02001548260600152505061018080516101a051610140516101c05180821015611e7e57600080fd5b80820390509050604051811115611e9457600080fd5b60605181830280604051901315611eaa57600080fd5b8091901215611eb857600080fd5b9050905060605181830380604051901315611ed257600080fd5b8091901215611ee057600080fd5b905090508152506000610180511215611efa576000610180525b610180516000811215611f0c57600080fd5b60005260206000f3505b005b634ee2cd7e6000511415612427573415611f3157600080fd5b6004356020518110611f4257600080fd5b50436024351115611f5257600080fd5b600061014052600660043560e05260c052604060c020546101605261018060006080818352015b6101605161014051101515611f8d5761205a565b6101405161016051818183011015611fa457600080fd5b808201905090506001818183011015611fbc57600080fd5b8082019050905060028080611fd057600080fd5b8204905090506101a05260243560036101a051633b9aca008110611ff357600080fd5b600560043560e05260c052604060c02060c052602060c0200160c052602060c020015411151561202a576101a05161014052612049565b6101a05160018082101561203d57600080fd5b80820390509050610160525b5b8151600101808352811415611f79575b50506101c061014051633b9aca00811061207357600080fd5b600560043560e05260c052604060c02060c052602060c020018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015260038160c052602060c020015482606001525050600354610240526101405161016051610180516101a0516101c0516101e051610200516102205161024051610260516024356102a052610240516102c0526102c0516102a05160065801611c4c565b61032052610260526102405261022052610200526101e0526101c0526101a0526101805261016052610140526103205161026052610340610260516c01431e0fae6d7217caa0000000811061217357600080fd5b600460c052602060c020018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015260038160c052602060c02001548260600152505060006103c05260006103e052610240516102605110156122a8576104006102605160018181830110156121f457600080fd5b808201905090506c01431e0fae6d7217caa0000000811061221457600080fd5b600460c052602060c020018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015260038160c052602060c020015482606001525050610460516103a0518082101561227857600080fd5b808203905090506103c05261044051610380518082101561229857600080fd5b808203905090506103e0526122e3565b436103a051808210156122ba57600080fd5b808203905090506103c0524261038051808210156122d757600080fd5b808203905090506103e0525b610380516104805260006103c05118156123655761048080516103e0516024356103a0518082101561231457600080fd5b80820390509050808202821582848304141761232f57600080fd5b809050905090506103c051808061234557600080fd5b82049050905081818301101561235a57600080fd5b808201905090508152505b6101c080516101e05161048051610200518082101561238357600080fd5b8082039050905060405181111561239957600080fd5b606051818302806040519013156123af57600080fd5b80919012156123bd57600080fd5b90509050606051818303806040519013156123d757600080fd5b80919012156123e557600080fd5b9050905081525060006101c051121515612419576101c051600081121561240b57600080fd5b60005260206000f350612425565b600060005260206000f3505b005b60001561262f575b6101e0526101405261016052610180526101a0526101c0526102006101408051825280602001518260200152806040015182604001528060600151826060015250506102405162093a80808061248457600080fd5b82049050905062093a8080820282158284830414176124a257600080fd5b80905090509050610280526102a0600060ff818352015b610280805162093a808181830110156124d157600080fd5b8082019050905081525060006102c0526101c0516102805111156124fc576101c05161028052612513565b60076102805160e05260c052604060c020546102c0525b61020080516102205161028051610240518082101561253157600080fd5b8082039050905060405181111561254757600080fd5b6060518183028060405190131561255d57600080fd5b809190121561256b57600080fd5b905090506060518183038060405190131561258557600080fd5b809190121561259357600080fd5b905090508152506101c0516102805114156125ad576125fa565b61022080516102c051606051818301806040519013156125cc57600080fd5b80919012156125da57600080fd5b9050905081525061028051610240525b81516001018083528114156124b9575b5050600061020051121561260f576000610200525b61020051600081121561262157600080fd5b6000526000516101e0515650005b6318160ddd600051141561264757426101405261266d565b63bd85b039600051141561266557602060046101403760005061266d565b600015612780575b341561267857600080fd5b60035461016052610180610160516c01431e0fae6d7217caa0000000811061269f57600080fd5b600460c052602060c020018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015260038160c052602060c0200154826060015250506101405161016051610180516101a0516101c0516101e051610220610180805182528060200151826020015280604001518260400152806060015182606001525050610140516102a0526102a051610280516102605161024051610220516006580161242f565b610300526101e0526101c0526101a0526101805261016052610140526103005160005260206000f350005b63981b24d06000511415612ae757341561279957600080fd5b4360043511156127a857600080fd5b6003546101405261014051610160516004356101a052610140516101c0526101c0516101a05160065801611c4c565b6102205261016052610140526102205161016052610240610160516c01431e0fae6d7217caa0000000811061280b57600080fd5b600460c052602060c020018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015260038160c052602060c02001548260600152505060006102c0526101405161016051101561298c576102e061016051600181818301101561288657600080fd5b808201905090506c01431e0fae6d7217caa000000081106128a657600080fd5b600460c052602060c020018060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015260038160c052602060c020015482606001525050610340516102a0511815612987576004356102a0518082101561291757600080fd5b8082039050905061032051610280518082101561293357600080fd5b80820390509050808202821582848304141761294e57600080fd5b80905090509050610340516102a0518082101561296a57600080fd5b80820390509050808061297c57600080fd5b8204905090506102c0525b612a16565b436102a0511815612a15576004356102a051808210156129ab57600080fd5b808203905090504261028051808210156129c457600080fd5b8082039050905080820282158284830414176129df57600080fd5b80905090509050436102a051808210156129f857600080fd5b808203905090508080612a0a57600080fd5b8204905090506102c0525b5b610140610360525b610360515160206103605101610360526102e0610360511015612a4057612a1e565b610380610240805182528060200151826020015280604001518260400152806060015182606001525050610280516102c051818183011015612a8157600080fd5b8082019050905061040052610400516103e0516103c0516103a051610380516006580161242f565b610460526102c0610360525b6103605152602061036051036103605261014061036051101515612ad857612ab5565b6104605160005260206000f350005b633cebb8236000511415612b28573415612b0057600080fd5b6004356020518110612b1157600080fd5b506008543314612b2057600080fd5b600435600855005b63fc0c546a6000511415612b4f573415612b4157600080fd5b60005460005260206000f350005b63047fc9aa6000511415612b76573415612b6857600080fd5b60015460005260206000f350005b63cbf9fe5f6000511415612bff573415612b8f57600080fd5b6004356020518110612ba057600080fd5b50610140808080600260043560e05260c052604060c02060c052602060c020548152505060208101905080806001600260043560e05260c052604060c02060c052602060c02001548152505060409050905060c05260c051610140f350005b63900cf0cf6000511415612c26573415612c1857600080fd5b60035460005260206000f350005b63d1febfb96000511415612d49573415612c3f57600080fd5b6101408080806004356c01431e0fae6d7217caa00000008110612c6157600080fd5b600460c052602060c0200160c052602060c0205481525050602081019050808060016004356c01431e0fae6d7217caa00000008110612c9f57600080fd5b600460c052602060c0200160c052602060c020015481525050602081019050808060026004356c01431e0fae6d7217caa00000008110612cde57600080fd5b600460c052602060c0200160c052602060c020015481525050602081019050808060036004356c01431e0fae6d7217caa00000008110612d1d57600080fd5b600460c052602060c0200160c052602060c02001548152505060809050905060c05260c051610140f350005b6328d09d476000511415612e92573415612d6257600080fd5b6004356020518110612d7357600080fd5b50610140808080602435633b9aca008110612d8d57600080fd5b600560043560e05260c052604060c02060c052602060c0200160c052602060c020548152505060208101905080806001602435633b9aca008110612dd057600080fd5b600560043560e05260c052604060c02060c052602060c0200160c052602060c02001548152505060208101905080806002602435633b9aca008110612e1457600080fd5b600560043560e05260c052604060c02060c052602060c0200160c052602060c02001548152505060208101905080806003602435633b9aca008110612e5857600080fd5b600560043560e05260c052604060c02060c052602060c0200160c052602060c02001548152505060809050905060c05260c051610140f350005b63010ae7576000511415612ed9573415612eab57600080fd5b6004356020518110612ebc57600080fd5b50600660043560e05260c052604060c0205460005260206000f350005b63711974846000511415612f0e573415612ef257600080fd5b600760043560e05260c052604060c0205460005260206000f350005b63f77c47916000511415612f35573415612f2757600080fd5b60085460005260206000f350005b63bef97c876000511415612f5c573415612f4e57600080fd5b60095460005260206000f350005b6306fdde036000511415613010573415612f7557600080fd5b600a8060c052602060c020610180602082540161012060006003818352015b82610120516020021115612fa757612fc9565b61012051850154610120516020028501525b8151600101808352811415612f94575b50505050505061018051806101a001818260206001820306601f82010390500336823750506020610160526040610180510160206001820306601f8201039050610160f350005b6395d89b4160005114156130c457341561302957600080fd5b600b8060c052602060c020610180602082540161012060006002818352015b8261012051602002111561305b5761307d565b61012051850154610120516020028501525b8151600101808352811415613048575b50505050505061018051806101a001818260206001820306601f82010390500336823750506020610160526040610180510160206001820306601f8201039050610160f350005b6354fd4d5060005114156131785734156130dd57600080fd5b600c8060c052602060c020610180602082540161012060006002818352015b8261012051602002111561310f57613131565b61012051850154610120516020028501525b81516001018083528114156130fc575b50505050505061018051806101a001818260206001820306601f82010390500336823750506020610160526040610180510160206001820306601f8201039050610160f350005b63313ce567600051141561319f57341561319157600080fd5b600d5460005260206000f350005b638ff36fd160005114156131c65734156131b857600080fd5b600e5460005260206000f350005b637175d4f760005114156131ed5734156131df57600080fd5b600f5460005260206000f350005b63f851a440600051141561321457341561320657600080fd5b60105460005260206000f350005b6317f7182a600051141561323b57341561322d57600080fd5b60115460005260206000f350005b5b60006000fd5b61030761354903610307600039610307613549036000f3000000000000000000000000d533a949740bb3306d119cc777fa900ba034cd52000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000011566f74652d657363726f7765642043525600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057665435256000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b76654352565f312e302e30000000000000000000000000000000000000000000","name":"Vyper_contract","is_blueprint":false,"license_type":"none","is_fully_verified":false,"is_verified_via_eth_bytecode_db":true,"language":"vyper","evm_version":null,"can_be_visualized_via_sol2uml":false,"is_verified_via_sourcify":false,"additional_sources":[],"certified":false,"conflicting_implementations":null,"abi":[{"anonymous":false,"inputs":[{"indexed":false,"name":"admin","type":"address"}],"name":"CommitOwnership","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"admin","type":"address"}],"name":"ApplyOwnership","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"provider","type":"address"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":true,"name":"locktime","type":"uint256"},{"indexed":false,"name":"type","type":"int128"},{"indexed":false,"name":"ts","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"provider","type":"address"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"ts","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"prevSupply","type":"uint256"},{"indexed":false,"name":"supply","type":"uint256"}],"name":"Supply","type":"event"},{"inputs":[{"name":"token_addr","type":"address"},{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_version","type":"string"}],"outputs":[],"stateMutability":"nonpayable","type":"constructor"},{"gas":37597,"inputs":[{"name":"addr","type":"address"}],"name":"commit_transfer_ownership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"gas":38497,"inputs":[],"name":"apply_transfer_ownership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"gas":36307,"inputs":[{"name":"addr","type":"address"}],"name":"commit_smart_wallet_checker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"gas":37095,"inputs":[],"name":"apply_smart_wallet_checker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"gas":2569,"inputs":[{"name":"addr","type":"address"}],"name":"get_last_user_slope","outputs":[{"name":"","type":"int128"}],"stateMutability":"view","type":"function"},{"gas":1672,"inputs":[{"name":"_addr","type":"address"},{"name":"_idx","type":"uint256"}],"name":"user_point_history__ts","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"gas":1593,"inputs":[{"name":"_addr","type":"address"}],"name":"locked__end","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"gas":37052342,"inputs":[],"name":"checkpoint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"gas":74279891,"inputs":[{"name":"_addr","type":"address"},{"name":"_value","type":"uint256"}],"name":"deposit_for","outputs":[],"stateMutability":"nonpayable","type":"function"},{"gas":74281465,"inputs":[{"name":"_value","type":"uint256"},{"name":"_unlock_time","type":"uint256"}],"name":"create_lock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"gas":74280830,"inputs":[{"name":"_value","type":"uint256"}],"name":"increase_amount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"gas":74281578,"inputs":[{"name":"_unlock_time","type":"uint256"}],"name":"increase_unlock_time","outputs":[],"stateMutability":"nonpayable","type":"function"},{"gas":37223566,"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"addr","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"addr","type":"address"},{"name":"_t","type":"uint256"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"gas":514333,"inputs":[{"name":"addr","type":"address"},{"name":"_block","type":"uint256"}],"name":"balanceOfAt","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"t","type":"uint256"}],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"gas":812560,"inputs":[{"name":"_block","type":"uint256"}],"name":"totalSupplyAt","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"gas":36907,"inputs":[{"name":"_newController","type":"address"}],"name":"changeController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"gas":1841,"inputs":[],"name":"token","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"gas":1871,"inputs":[],"name":"supply","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"gas":3359,"inputs":[{"name":"arg0","type":"address"}],"name":"locked","outputs":[{"name":"amount","type":"int128"},{"name":"end","type":"uint256"}],"stateMutability":"view","type":"function"},{"gas":1931,"inputs":[],"name":"epoch","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"gas":5550,"inputs":[{"name":"arg0","type":"uint256"}],"name":"point_history","outputs":[{"name":"bias","type":"int128"},{"name":"slope","type":"int128"},{"name":"ts","type":"uint256"},{"name":"blk","type":"uint256"}],"stateMutability":"view","type":"function"},{"gas":6079,"inputs":[{"name":"arg0","type":"address"},{"name":"arg1","type":"uint256"}],"name":"user_point_history","outputs":[{"name":"bias","type":"int128"},{"name":"slope","type":"int128"},{"name":"ts","type":"uint256"},{"name":"blk","type":"uint256"}],"stateMutability":"view","type":"function"},{"gas":2175,"inputs":[{"name":"arg0","type":"address"}],"name":"user_point_epoch","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"gas":2166,"inputs":[{"name":"arg0","type":"uint256"}],"name":"slope_changes","outputs":[{"name":"","type":"int128"}],"stateMutability":"view","type":"function"},{"gas":2081,"inputs":[],"name":"controller","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"gas":2111,"inputs":[],"name":"transfersEnabled","outputs":[{"name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"gas":8543,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"stateMutability":"view","type":"function"},{"gas":7596,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"stateMutability":"view","type":"function"},{"gas":7626,"inputs":[],"name":"version","outputs":[{"name":"","type":"string"}],"stateMutability":"view","type":"function"},{"gas":2231,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"gas":2261,"inputs":[],"name":"future_smart_wallet_checker","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"gas":2291,"inputs":[],"name":"smart_wallet_checker","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"gas":2321,"inputs":[],"name":"admin","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"gas":2351,"inputs":[],"name":"future_admin","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":true,"constructor_args":"0x000000000000000000000000d533a949740bb3306d119cc777fa900ba034cd52000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000011566f74652d657363726f7765642043525600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057665435256000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b76654352565f312e302e30000000000000000000000000000000000000000000"}