Overview
Max Total Supply
20,268,612.40425396622022979 veBUNNI
Holders
0
Transfers
-
0
Market
Onchain Market Cap
-
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Loading...
Loading
Loading...
Loading
Loading...
Loading
| # | Exchange | Pair | Price | 24H Volume | % Volume |
|---|
Contract Source Code Verified (Exact Match)
Contract Name:
Voting Escrow
Compiler Version
vyper:0.4.0
Contract Source Code (Vyper language format)
#pragma version ^0.4.0
"""
@title Voting Escrow
@author Curve Finance
@license MIT
@notice Votes have a weight depending on time, so that users are
committed to the future of (whatever they are voting for)
@dev Vote weight decays linearly over time. Lock time cannot be
more than `MAXTIME` (1 year).
"""
MULTICALLER_WITH_SENDER: constant(address) = 0x00000000002Fd5Aeb385D324B580FCa7c83823A0
MULTICALLER_WITH_SIGNER: constant(address) = 0x000000000000D9ECebf3C23529de49815Dac1c4c
@internal
@view
def sender_or_signer() -> address:
if msg.sender in [MULTICALLER_WITH_SENDER, MULTICALLER_WITH_SIGNER]:
response: Bytes[32] = raw_call(msg.sender, b"", max_outsize=32, is_static_call=True)
# the sender is encoded in the last 20 bytes of the response
return extract32(response, 0, output_type=address)
else:
return msg.sender
# Voting escrow to have time-weighted votes
# Votes have a weight depending on time, so that users are committed
# to the future of (whatever they are voting for).
# The weight in this implementation is linear, and lock cannot be more than maxtime:
# w ^
# 1 + /
# | /
# | /
# | /
# |/
# 0 +--------+------> time
# maxtime (1 year)
##
# SECTION INTERFACES
##
from ethereum.ercs import IERC20 as ERC20
from ethereum.ercs import IERC20Detailed
# Interface for checking whether address belongs to a whitelisted
# type of a smart wallet.
# When new types are added - the whole contract is changed
# The check() method is modifying to be able to use caching
# for individual wallet addresses
interface SmartWalletChecker:
def check(addr: address) -> bool: nonpayable
implements: IERC20Detailed
# !SECTION INTERFACES
##
# SECTION STRUCTS
##
# We cannot really do block numbers per se b/c slope is per time, not per block
# and per block could be fairly bad b/c Ethereum changes blocktimes.
# What we can do is to extrapolate ***At functions
struct Point:
bias: int128
slope: int128 # - dweight // dt
ts: uint256
blk: uint256 # block
struct LockedBalance:
amount: int128
end: uint256
# !SECTION STRUCTS
##
# SECTION EVENTS
##
CREATE_LOCK_TYPE: constant(int128) = 1
INCREASE_LOCK_AMOUNT: constant(int128) = 2
INCREASE_UNLOCK_TIME: constant(int128) = 3
AIRDROP_LOCK_TYPE: constant(int128) = 4
event Deposit:
provider: indexed(address)
value: uint256
locktime: indexed(uint256)
type: int128
ts: uint256
event Withdraw:
provider: indexed(address)
value: uint256
ts: uint256
event Supply:
prevSupply: uint256
supply: uint256
event NewPendingAdmin:
new_pending_admin: address
event NewAdmin:
new_admin: address
event NewPendingSmartWalletChecker:
new_pending_smart_wallet_checker: indexed(address)
event NewSmartWalletChecker:
new_smart_wallet_checker: indexed(address)
event BurnUnlockFuse: pass
event ApproveAirdrop:
locker: indexed(address)
airdropper: indexed(address)
# !SECTION EVENTS
##
# SECTION CONSTANTS
##
WEEK: constant(uint256) = 7 * 86400 # all future times are rounded by week
MAXTIME: constant(uint256) = 365 * 86400 # 1 year
MULTIPLIER: constant(uint256) = 10 ** 18
# !SECTION CONSTANTS
##
# SECTION IMMUTABLES
##
TOKEN: immutable(address)
NAME: immutable(String[64])
SYMBOL: immutable(String[32])
DECIMALS: immutable(uint8)
# !SECTION IMMUTABLES
##
# SECTION STORAGE
##
pending_admin: public(address)
admin: public(address)
supply: public(uint256)
locked: public(HashMap[address, LockedBalance])
# Checker for whitelisted (smart contract) wallets which are allowed to deposit
# The goal is to prevent tokenizing the escrow
future_smart_wallet_checker: public(address)
smart_wallet_checker: public(address)
epoch: public(uint256)
user_point_history: public(HashMap[address, Point[1000000000]]) # user -> Point[user_epoch]
user_point_epoch: public(HashMap[address, uint256])
slope_changes: public(HashMap[uint256, int128]) # time -> signed slope change
point_history: public(Point[100000000000000000000000000000]) # epoch -> unsigned point
unlock_fuse: public(bool) # Can be permanently set to true to unlock all positions
# !SECTION STORAGE
##
# SECTION TRANSIENT STORAGE
##
# Lockers can allow another address to airdrop locked tokens to them and increase their lock time to the maximum.
# Transient storage is used so that such approvals only last for the duration of the transaction.
allow_airdrop: public(transient(HashMap[address, HashMap[address, bool]])) # locker -> airdropper -> allowed
# !SECTION TRANSIENT STORAGE
##
# SECTION CONSTRUCTOR
##
@deploy
def __init__(token_addr: address, _name: String[64], _symbol: String[32], _admin: address, _smart_wallet_checker: address):
"""
@notice Contract constructor
@param token_addr The token to escrow
@param _name Token name
@param _symbol Token symbol
@param _admin The admin address
"""
assert _admin != empty(address)
TOKEN = token_addr
self.admin = _admin
self.point_history[0].blk = block.number
self.point_history[0].ts = block.timestamp
self.smart_wallet_checker = _smart_wallet_checker
_decimals: uint8 = staticcall IERC20Detailed(token_addr).decimals()
NAME = _name
SYMBOL = _symbol
DECIMALS = _decimals
# !SECTION CONSTRUCTOR
##
# SECTION PUBLIC GETTERS
##
@external
@view
def token() -> address:
return TOKEN
@external
@view
def name() -> String[64]:
return NAME
@external
@view
def symbol() -> String[32]:
return SYMBOL
@external
@view
def decimals() -> uint8:
return DECIMALS
@external
@view
def get_last_user_slope(addr: address) -> int128:
"""
@notice Get the most recently recorded rate of voting power decrease for `addr`
@param addr Address of the user wallet
@return Value of the slope
"""
uepoch: uint256 = self.user_point_epoch[addr]
return self.user_point_history[addr][uepoch].slope
@external
@view
def user_point_history__ts(_addr: address, _idx: uint256) -> uint256:
"""
@notice Get the timestamp for checkpoint `_idx` for `_addr`
@param _addr User wallet address
@param _idx User epoch number
@return Epoch time of the checkpoint
"""
return self.user_point_history[_addr][_idx].ts
@external
@view
def locked__end(_addr: address) -> uint256:
"""
@notice Get timestamp when `_addr`'s lock finishes
@param _addr User wallet
@return Epoch time of the lock end
"""
return self.locked[_addr].end
@external
@view
def balanceOf(addr: address, _t: uint256 = block.timestamp) -> uint256:
"""
@notice Get the current voting power for `addr`
@dev Adheres to the ERC20 `balanceOf` interface for Aragon compatibility
@param addr User wallet address
@param _t Epoch time to return voting power at
@return User voting power
"""
_epoch: uint256 = 0
if _t == block.timestamp:
# No need to do binary search, will always live in current epoch
_epoch = self.user_point_epoch[addr]
else:
_epoch = self.find_timestamp_user_epoch(addr, _t, self.user_point_epoch[addr])
if _epoch == 0:
return 0
else:
last_point: Point = self.user_point_history[addr][_epoch]
last_point.bias -= last_point.slope * convert(_t - last_point.ts, int128)
if last_point.bias < 0:
last_point.bias = 0
return convert(last_point.bias, uint256)
@external
@view
def balanceOfAt(addr: address, _block: uint256) -> uint256:
"""
@notice Measure voting power of `addr` at block height `_block`
@dev Adheres to MiniMe `balanceOfAt` interface: https://github.com/Giveth/minime
@param addr User's wallet address
@param _block Block to calculate the voting power at
@return Voting power
"""
# Copying and pasting totalSupply code because Vyper cannot pass by
# reference yet
assert _block <= block.number
_user_epoch: uint256 = self.find_block_user_epoch(addr, _block, self.user_point_epoch[addr])
upoint: Point = self.user_point_history[addr][_user_epoch]
max_epoch: uint256 = self.epoch
_epoch: uint256 = self.find_block_epoch(_block, max_epoch)
point_0: Point = self.point_history[_epoch]
d_block: uint256 = 0
d_t: uint256 = 0
if _epoch < max_epoch:
point_1: Point = self.point_history[_epoch + 1]
d_block = point_1.blk - point_0.blk
d_t = point_1.ts - point_0.ts
else:
d_block = block.number - point_0.blk
d_t = block.timestamp - point_0.ts
block_time: uint256 = point_0.ts
if d_block != 0:
block_time += d_t * (_block - point_0.blk) // d_block
upoint.bias -= upoint.slope * convert(block_time - upoint.ts, int128)
if upoint.bias >= 0:
return convert(upoint.bias, uint256)
else:
return 0
@external
@view
def totalSupply(t: uint256 = block.timestamp) -> uint256:
"""
@notice Calculate total voting power
@dev Adheres to the ERC20 `totalSupply` interface for Aragon compatibility
@return Total voting power
"""
_epoch: uint256 = 0
if t == block.timestamp:
# No need to do binary search, will always live in current epoch
_epoch = self.epoch
else:
_epoch = self.find_timestamp_epoch(t, self.epoch)
if _epoch == 0:
return 0
else:
last_point: Point = self.point_history[_epoch]
return self.supply_at(last_point, t)
@external
@view
def totalSupplyAt(_block: uint256) -> uint256:
"""
@notice Calculate total voting power at some point in the past
@param _block Block to calculate the total voting power at
@return Total voting power at `_block`
"""
assert _block <= block.number
_epoch: uint256 = self.epoch
target_epoch: uint256 = self.find_block_epoch(_block, _epoch)
point: Point = self.point_history[target_epoch]
dt: uint256 = 0
if target_epoch < _epoch:
point_next: Point = self.point_history[target_epoch + 1]
if point.blk != point_next.blk:
dt = (_block - point.blk) * (point_next.ts - point.ts) // (point_next.blk - point.blk)
else:
if point.blk != block.number:
dt = (_block - point.blk) * (block.timestamp - point.ts) // (block.number - point.blk)
# Now dt contains info on how far are we beyond point
return self.supply_at(point, point.ts + dt)
# !SECTION PUBLIC GETTERS
##
# SECTION LOCKER ACTIONS
#
@external
def checkpoint():
"""
@notice Record global data to checkpoint
"""
self._checkpoint(empty(address), empty(LockedBalance), empty(LockedBalance))
@external
@nonreentrant
def create_lock(_value: uint256, _unlock_time: uint256):
"""
@notice Deposit `_value` tokens for `msg.sender` and lock until `_unlock_time`
@param _value Amount to deposit
@param _unlock_time Epoch time when tokens unlock, rounded down to whole weeks
"""
msg_sender: address = self.sender_or_signer()
self.assert_not_contract(msg_sender)
unlock_time: uint256 = (_unlock_time // WEEK) * WEEK # Locktime is rounded down to weeks
_locked: LockedBalance = self.locked[msg_sender]
assert _value > 0 # dev: need non-zero value
assert _locked.amount == 0, "Withdraw old tokens first"
assert unlock_time > block.timestamp, "Can only lock until time in the future"
assert unlock_time <= block.timestamp + MAXTIME, "Voting lock can be 1 year max"
self._deposit_for(msg_sender, _value, unlock_time, _locked, CREATE_LOCK_TYPE)
@external
@nonreentrant
def increase_amount(_value: uint256):
"""
@notice Deposit `_value` additional tokens for `msg.sender`
without modifying the unlock time
@param _value Amount of tokens to deposit and add to the lock
"""
msg_sender: address = self.sender_or_signer()
self.assert_not_contract(msg_sender)
_locked: LockedBalance = self.locked[msg_sender]
assert _value > 0 # dev: need non-zero value
assert _locked.amount > 0, "No existing lock found"
assert _locked.end > block.timestamp, "Cannot add to expired lock. Withdraw"
self._deposit_for(msg_sender, _value, 0, _locked, INCREASE_LOCK_AMOUNT)
@external
@nonreentrant
def increase_unlock_time(_unlock_time: uint256):
"""
@notice Extend the unlock time for `msg.sender` to `_unlock_time`
@param _unlock_time New epoch time for unlocking
"""
msg_sender: address = self.sender_or_signer()
self.assert_not_contract(msg_sender)
_locked: LockedBalance = self.locked[msg_sender]
unlock_time: uint256 = (_unlock_time // WEEK) * WEEK # Locktime is rounded down to weeks
assert _locked.end > block.timestamp, "Lock expired"
assert _locked.amount > 0, "Nothing is locked"
assert unlock_time > _locked.end, "Can only increase lock duration"
assert unlock_time <= block.timestamp + MAXTIME, "Voting lock can be 1 year max"
self._deposit_for(msg_sender, 0, unlock_time, _locked, INCREASE_UNLOCK_TIME)
@external
@nonreentrant
def withdraw():
"""
@notice Withdraw all tokens for `msg.sender`
@dev Only possible if the lock has expired
"""
msg_sender: address = self.sender_or_signer()
_locked: LockedBalance = self.locked[msg_sender]
assert (block.timestamp >= _locked.end) or self.unlock_fuse, "The lock didn't expire or the unlock fuse has not been burnt"
value: uint256 = convert(_locked.amount, uint256)
old_locked: LockedBalance = _locked
_locked.end = 0
_locked.amount = 0
self.locked[msg_sender] = _locked
supply_before: uint256 = self.supply
self.supply = supply_before - value
# old_locked can have either expired <= timestamp or zero end
# _locked has only 0 end
# Both can have >= 0 amount
self._checkpoint(msg_sender, old_locked, _locked)
assert extcall ERC20(TOKEN).transfer(msg_sender, value)
log Withdraw(msg_sender, value, block.timestamp)
log Supply(supply_before, supply_before - value)
@external
def approve_airdrop(airdropper: address):
"""
@notice Approve an address to airdrop locked tokens to the caller for the duration of the transaction.
@param airdropper The address that will be allowed to airdrop tokens.
"""
msg_sender: address = self.sender_or_signer()
self.allow_airdrop[msg_sender][airdropper] = True
log ApproveAirdrop(msg_sender, airdropper)
# !SECTION LOCKER ACTIONS
##
# SECTION AIRDROPPER ACTIONS
##
@external
@nonreentrant
def airdrop(_to: address, _value: uint256, _unlock_time: uint256):
msg_sender: address = self.sender_or_signer()
self.assert_not_contract(_to)
unlock_time: uint256 = (_unlock_time // WEEK) * WEEK # Locktime is rounded down to weeks
_locked: LockedBalance = self.locked[_to]
assert _value > 0 # dev: need non-zero value
assert unlock_time > block.timestamp, "Can only lock until time in the future"
assert unlock_time <= block.timestamp + MAXTIME, "Voting lock can be 1 year max"
assert self.allow_airdrop[_to][msg_sender], "Airdrop not allowed"
# update supply
supply_before: uint256 = self.supply
self.supply = supply_before + _value
# update locked balance
old_locked: LockedBalance = _locked
# airdropper can only extend the lock time, not decrease it
_locked.amount += convert(_value, int128)
_locked.end = max(unlock_time, _locked.end)
self.locked[_to] = _locked
# checkpoint the user's locked balance
self._checkpoint(_to, old_locked, _locked)
# transfer tokens from the airdropper
assert extcall ERC20(TOKEN).transferFrom(msg_sender, self, _value)
log Deposit(_to, _value, _locked.end, AIRDROP_LOCK_TYPE, block.timestamp)
log Supply(supply_before, supply_before + _value)
# !SECTION AIRDROPPER ACTIONS
##
# SECTION ADMIN ACTIONS
##
@external
def commit_smart_wallet_checker(addr: address):
"""
@notice Set an external contract to check for approved smart contract wallets
@param addr Address of Smart contract checker
"""
assert msg.sender == self.admin
self.future_smart_wallet_checker = addr
log NewPendingSmartWalletChecker(addr)
@external
def apply_smart_wallet_checker():
"""
@notice Apply setting external contract to check approved smart contract wallets
"""
assert msg.sender == self.admin
new_checker: address = self.future_smart_wallet_checker
self.smart_wallet_checker = new_checker
log NewSmartWalletChecker(new_checker)
@external
def burn_unlock_fuse():
"""
@notice Burn unlock fuse permanently and allow all users to withdraw
"""
assert msg.sender == self.admin
self.unlock_fuse = True
log BurnUnlockFuse()
@external
def change_pending_admin(new_pending_admin: address):
"""
@notice Change pending_admin to `new_pending_admin`
@param new_pending_admin The new pending_admin address
"""
assert msg.sender == self.admin
self.pending_admin = new_pending_admin
log NewPendingAdmin(new_pending_admin)
@external
def claim_admin():
"""
@notice Called by pending_admin to set admin to pending_admin
"""
assert msg.sender == self.pending_admin
self.admin = msg.sender
self.pending_admin = empty(address)
log NewAdmin(msg.sender)
# !SECTION ADMIN ACTIONS
##
# SECTION INTERNAL UTILITIES
##
@internal
@view
def find_block_epoch(_block: uint256, max_epoch: uint256) -> uint256:
"""
@notice Binary search to find epoch containing block number
@param _block Block to find
@param max_epoch Don't go beyond this epoch
@return Epoch which contains _block
"""
# Binary search
_min: uint256 = 0
_max: uint256 = max_epoch
for i: uint256 in range(128): # Will be always enough for 128-bit numbers
if _min >= _max:
break
_mid: uint256 = (_min + _max + 1) // 2
if self.point_history[_mid].blk <= _block:
_min = _mid
else:
_max = _mid - 1
return _min
@internal
@view
def find_timestamp_epoch(_timestamp: uint256, max_epoch: uint256) -> uint256:
"""
@notice Binary search to find epoch for timestamp
@param _timestamp timestamp to find
@param max_epoch Don't go beyond this epoch
@return Epoch which contains _timestamp
"""
# Binary search
_min: uint256 = 0
_max: uint256 = max_epoch
for i: uint256 in range(128): # Will be always enough for 128-bit numbers
if _min >= _max:
break
_mid: uint256 = (_min + _max + 1) // 2
if self.point_history[_mid].ts <= _timestamp:
_min = _mid
else:
_max = _mid - 1
return _min
@internal
@view
def find_block_user_epoch(_addr: address, _block: uint256, max_epoch: uint256) -> uint256:
"""
@notice Binary search to find epoch for block number
@param _addr User for which to find user epoch for
@param _block Block to find
@param max_epoch Don't go beyond this epoch
@return Epoch which contains _block
"""
# Binary search
_min: uint256 = 0
_max: uint256 = max_epoch
for i: uint256 in range(128): # Will be always enough for 128-bit numbers
if _min >= _max:
break
_mid: uint256 = (_min + _max + 1) // 2
if self.user_point_history[_addr][_mid].blk <= _block:
_min = _mid
else:
_max = _mid - 1
return _min
@internal
@view
def find_timestamp_user_epoch(_addr: address, _timestamp: uint256, max_epoch: uint256) -> uint256:
"""
@notice Binary search to find user epoch for timestamp
@param _addr User for which to find user epoch for
@param _timestamp timestamp to find
@param max_epoch Don't go beyond this epoch
@return Epoch which contains _timestamp
"""
# Binary search
_min: uint256 = 0
_max: uint256 = max_epoch
for i: uint256 in range(128): # Will be always enough for 128-bit numbers
if _min >= _max:
break
_mid: uint256 = (_min + _max + 1) // 2
if self.user_point_history[_addr][_mid].ts <= _timestamp:
_min = _mid
else:
_max = _mid - 1
return _min
@internal
@view
def supply_at(point: Point, t: uint256) -> uint256:
"""
@notice Calculate total voting power at some point in the past
@param point The point (bias/slope) to start search from
@param t Time to calculate the total voting power at
@return Total voting power at that time
"""
last_point: Point = point
t_i: uint256 = (last_point.ts // WEEK) * WEEK
for i: uint256 in range(255):
t_i += WEEK
d_slope: int128 = 0
if t_i > t:
t_i = t
else:
d_slope = self.slope_changes[t_i]
last_point.bias -= last_point.slope * convert(t_i - last_point.ts, int128)
if t_i == t:
break
last_point.slope += d_slope
last_point.ts = t_i
if last_point.bias < 0:
last_point.bias = 0
return convert(last_point.bias, uint256)
@internal
def assert_not_contract(addr: address):
"""
@notice Check if the call is from a whitelisted smart contract, revert if not
@param addr Address to be checked
"""
if addr != tx.origin:
checker: address = self.smart_wallet_checker
if checker != empty(address):
if extcall SmartWalletChecker(checker).check(addr):
return
raise "Smart contract depositors not allowed"
@internal
def _checkpoint(addr: address, old_locked: LockedBalance, new_locked: LockedBalance):
"""
@notice Record global and per-user data to checkpoint
@param addr User's wallet address. No user checkpoint if 0x0
@param old_locked Pevious locked amount / end lock time for the user
@param new_locked New locked amount / end lock time for the user
"""
u_old: Point = empty(Point)
u_new: Point = empty(Point)
old_dslope: int128 = 0
new_dslope: int128 = 0
_epoch: uint256 = self.epoch
if addr != empty(address):
# Calculate slopes and biases
# Kept at zero when they have to
if old_locked.end > block.timestamp and old_locked.amount > 0:
u_old.slope = old_locked.amount // convert(MAXTIME, int128)
u_old.bias = u_old.slope * convert(old_locked.end - block.timestamp, int128)
if new_locked.end > block.timestamp and new_locked.amount > 0:
u_new.slope = new_locked.amount // convert(MAXTIME, int128)
u_new.bias = u_new.slope * convert(new_locked.end - block.timestamp, int128)
# Read values of scheduled changes in the slope
# old_locked.end can be in the past and in the future
# new_locked.end can ONLY by in the FUTURE unless everything expired: than zeros
old_dslope = self.slope_changes[old_locked.end]
if new_locked.end != 0:
if new_locked.end == old_locked.end:
new_dslope = old_dslope
else:
new_dslope = self.slope_changes[new_locked.end]
last_point: Point = Point(bias=0, slope=0, ts=block.timestamp, blk=block.number)
if _epoch > 0:
last_point = self.point_history[_epoch]
last_checkpoint: uint256 = last_point.ts
# initial_last_point is used for extrapolation to calculate block number
# (approximately, for *At methods) and save them
# as we cannot figure that out exactly from inside the contract
initial_last_point: Point = last_point
block_slope: uint256 = 0 # dblock/dt
if block.timestamp > last_point.ts:
block_slope = MULTIPLIER * (block.number - last_point.blk) // (block.timestamp - last_point.ts)
# If last point is already recorded in this block, slope=0
# But that's ok b/c we know the block in such case
# Go over weeks to fill history and calculate what the current point is
t_i: uint256 = (last_checkpoint // WEEK) * WEEK
for i: uint256 in range(255):
# Hopefully it won't happen that this won't get used in 5 years!
# If it does, users will be able to withdraw but vote weight will be broken
t_i += WEEK
d_slope: int128 = 0
if t_i > block.timestamp:
t_i = block.timestamp
else:
d_slope = self.slope_changes[t_i]
last_point.bias -= last_point.slope * convert(t_i - last_checkpoint, int128)
last_point.slope += d_slope
if last_point.bias < 0: # This can happen
last_point.bias = 0
if last_point.slope < 0: # This cannot happen - just in case
last_point.slope = 0
last_checkpoint = t_i
last_point.ts = t_i
last_point.blk = initial_last_point.blk + block_slope * (t_i - initial_last_point.ts) // MULTIPLIER
_epoch += 1
if t_i == block.timestamp:
last_point.blk = block.number
break
else:
self.point_history[_epoch] = last_point
self.epoch = _epoch
# Now point_history is filled until t=now
if addr != empty(address):
# If last point was in this block, the slope change has been applied already
# But in such case we have 0 slope(s)
last_point.slope += (u_new.slope - u_old.slope)
last_point.bias += (u_new.bias - u_old.bias)
if last_point.slope < 0:
last_point.slope = 0
if last_point.bias < 0:
last_point.bias = 0
# Record the changed point into history
self.point_history[_epoch] = last_point
if addr != empty(address):
# Schedule the slope changes (slope is going down)
# We subtract new_user_slope from [new_locked.end]
# and add old_user_slope to [old_locked.end]
if old_locked.end > block.timestamp:
# old_dslope was <something> - u_old.slope, so we cancel that
old_dslope += u_old.slope
if new_locked.end == old_locked.end:
old_dslope -= u_new.slope # It was a new deposit, not extension
self.slope_changes[old_locked.end] = old_dslope
if new_locked.end > block.timestamp:
if new_locked.end > old_locked.end:
new_dslope -= u_new.slope # old slope disappeared at this point
self.slope_changes[new_locked.end] = new_dslope
# else: we recorded it already in old_dslope
# Now handle user history
user_epoch: uint256 = self.user_point_epoch[addr] + 1
self.user_point_epoch[addr] = user_epoch
u_new.ts = block.timestamp
u_new.blk = block.number
self.user_point_history[addr][user_epoch] = u_new
@internal
def _deposit_for(_addr: address, _value: uint256, unlock_time: uint256, locked_balance: LockedBalance, type: int128):
"""
@notice Deposit and lock tokens for a user
@param _addr User's wallet address
@param _value Amount to deposit
@param unlock_time New time when to unlock the tokens, or 0 if unchanged
@param locked_balance Previous locked amount / timestamp
"""
_locked: LockedBalance = locked_balance
supply_before: uint256 = self.supply
self.supply = supply_before + _value
old_locked: LockedBalance = _locked
# Adding to existing lock, or if a lock is expired - creating a new one
_locked.amount += convert(_value, int128)
if unlock_time != 0:
_locked.end = unlock_time
self.locked[_addr] = _locked
# Possibilities:
# Both old_locked.end could be current or expired (>/< block.timestamp)
# value == 0 (extend lock) or value > 0 (add to lock or extend lock)
# _locked.end > block.timestamp (always)
self._checkpoint(_addr, old_locked, _locked)
if _value != 0:
assert extcall ERC20(TOKEN).transferFrom(_addr, self, _value)
log Deposit(_addr, _value, _locked.end, type, block.timestamp)
log Supply(supply_before, supply_before + _value)
# !SECTION INTERNAL UTILITIESContract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"name":"Deposit","inputs":[{"name":"provider","type":"address","indexed":true},{"name":"value","type":"uint256","indexed":false},{"name":"locktime","type":"uint256","indexed":true},{"name":"type","type":"int128","indexed":false},{"name":"ts","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"Withdraw","inputs":[{"name":"provider","type":"address","indexed":true},{"name":"value","type":"uint256","indexed":false},{"name":"ts","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"Supply","inputs":[{"name":"prevSupply","type":"uint256","indexed":false},{"name":"supply","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"NewPendingAdmin","inputs":[{"name":"new_pending_admin","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"NewAdmin","inputs":[{"name":"new_admin","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"NewPendingSmartWalletChecker","inputs":[{"name":"new_pending_smart_wallet_checker","type":"address","indexed":true}],"anonymous":false,"type":"event"},{"name":"NewSmartWalletChecker","inputs":[{"name":"new_smart_wallet_checker","type":"address","indexed":true}],"anonymous":false,"type":"event"},{"name":"BurnUnlockFuse","inputs":[],"anonymous":false,"type":"event"},{"name":"ApproveAirdrop","inputs":[{"name":"locker","type":"address","indexed":true},{"name":"airdropper","type":"address","indexed":true}],"anonymous":false,"type":"event"},{"stateMutability":"view","type":"function","name":"token","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"name","inputs":[],"outputs":[{"name":"","type":"string"}]},{"stateMutability":"view","type":"function","name":"symbol","inputs":[],"outputs":[{"name":"","type":"string"}]},{"stateMutability":"view","type":"function","name":"decimals","inputs":[],"outputs":[{"name":"","type":"uint8"}]},{"stateMutability":"view","type":"function","name":"get_last_user_slope","inputs":[{"name":"addr","type":"address"}],"outputs":[{"name":"","type":"int128"}]},{"stateMutability":"view","type":"function","name":"user_point_history__ts","inputs":[{"name":"_addr","type":"address"},{"name":"_idx","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"locked__end","inputs":[{"name":"_addr","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"balanceOf","inputs":[{"name":"addr","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"balanceOf","inputs":[{"name":"addr","type":"address"},{"name":"_t","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"balanceOfAt","inputs":[{"name":"addr","type":"address"},{"name":"_block","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"totalSupply","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"totalSupply","inputs":[{"name":"t","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"totalSupplyAt","inputs":[{"name":"_block","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"checkpoint","inputs":[],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"create_lock","inputs":[{"name":"_value","type":"uint256"},{"name":"_unlock_time","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"increase_amount","inputs":[{"name":"_value","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"increase_unlock_time","inputs":[{"name":"_unlock_time","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"withdraw","inputs":[],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"approve_airdrop","inputs":[{"name":"airdropper","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"airdrop","inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"},{"name":"_unlock_time","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"commit_smart_wallet_checker","inputs":[{"name":"addr","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"apply_smart_wallet_checker","inputs":[],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"burn_unlock_fuse","inputs":[],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"change_pending_admin","inputs":[{"name":"new_pending_admin","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"claim_admin","inputs":[],"outputs":[]},{"stateMutability":"view","type":"function","name":"pending_admin","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"admin","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"supply","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"locked","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"tuple","components":[{"name":"amount","type":"int128"},{"name":"end","type":"uint256"}]}]},{"stateMutability":"view","type":"function","name":"future_smart_wallet_checker","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"smart_wallet_checker","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"epoch","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"user_point_history","inputs":[{"name":"arg0","type":"address"},{"name":"arg1","type":"uint256"}],"outputs":[{"name":"","type":"tuple","components":[{"name":"bias","type":"int128"},{"name":"slope","type":"int128"},{"name":"ts","type":"uint256"},{"name":"blk","type":"uint256"}]}]},{"stateMutability":"view","type":"function","name":"user_point_epoch","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"slope_changes","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"int128"}]},{"stateMutability":"view","type":"function","name":"point_history","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"tuple","components":[{"name":"bias","type":"int128"},{"name":"slope","type":"int128"},{"name":"ts","type":"uint256"},{"name":"blk","type":"uint256"}]}]},{"stateMutability":"view","type":"function","name":"unlock_fuse","inputs":[],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"view","type":"function","name":"allow_airdrop","inputs":[{"name":"arg0","type":"address"},{"name":"arg1","type":"address"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"nonpayable","type":"constructor","inputs":[{"name":"token_addr","type":"address"},{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_admin","type":"address"},{"name":"_smart_wallet_checker","type":"address"}],"outputs":[]}]Contract Creation Code
612b3c515034610199576020612c2f5f395f518060a01c610199576040526020612c4f5f395f51602081612c2f015f395f516040811161019957506020602082612c2f015f395f51018082612c2f0160603950506020612c6f5f395f51602081612c2f015f395f516020811161019957506020602082612c2f015f395f51018082612c2f0160c03950506020612c8f5f395f518060a01c61019957610100526020612caf5f395f518060a01c6101995761012052610100511561019957604051612a7c526101005160015543600d5542600c556101205160055560405163313ce567610160526020610160600461017c845afa6100fe573d5f5f3e3d5ffd5b3d602081183d602010021880610160016101801161019957610160518060081c610199576101a052506101a0905051610140526020606051015f81601f0160051c6003811161019957801561016e57905b8060051b606001518160051b602001612a7c015260010181811861014f575b50505060c051612afc5260e051612b1c5261014051612b3c52612a7c61019d61000039612b5c610000f35b5f80fd5f3560e01c60026021820660011b612a3a01601e395f51565b63fc0c546a8118611c175734612a36576020612a7c60403960206040f35b6306fdde03811861008c5734612a36576020806040528060400160206020612a9c5f395f510180612a9c8339508051806020830101601f825f03163682375050601f19601f825160200101169050810190506040f35b6318160ddd81186100a65734612a3657426101c052610c5f565b63a3ce42d08118611c175734612a36575f543318612a3657336001555f5f557f71614071b88dee5e0b2ae578a9dd7b2ebbe9ae832ba419dc0242cd065a290b6c3360405260206040a1005b6395d89b418118611c175734612a36576020806040528060400160206020612afc5f395f510180612afc8339508051806020830101601f825f03163682375050601f19601f825160200101169050810190506040f35b63313ce5678118611c175734612a36576020612b3c60403960206040f35b637c74a17481186101ce57602436103417612a36576004358060a01c612a365760405260086040516020525f5260405f205460605260076040516020525f5260405f20606051633b9aca00811015612a365760021b810190506001810190505460805260206080f35b6370a0823181186101ed57602436103417612a36574261014052610777565b636cf492d38118611c175734612a36576c050c783eb9b5c85f2a8000000a5460405260206040f35b63da020a18811861026c57604436103417612a36576004358060a01c612a365760405260076040516020525f5260405f20602435633b9aca00811015612a365760021b810190506002810190505460605260206060f35b63e1bc2967811861069357606436103417612a36576004358060a01c612a36576103e0525f5c600114612a365760015f5d6102a86104206126ad565b61042051610400526103e0516040526102bf612774565b60443562093a808104905062093a8081028162093a80820418612a365790506104205260036103e0516020525f5260405f208054610440526001810154610460525060243515612a36574261042051116103b557602080610500526026610480527f43616e206f6e6c79206c6f636b20756e74696c2074696d6520696e20746865206104a0527f66757475726500000000000000000000000000000000000000000000000000006104c052610480816105000160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06104e052806004016104fcfd5b426301e133808101818110612a3657905061042051111561044d576020806104e052601d610480527f566f74696e67206c6f636b2063616e20626520312079656172206d61780000006104a052610480816104e00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06104c052806004016104dcfd5b60016103e0516020525f5260405f2080610400516020525f5260405f2090505c6104ee576020806104e0526013610480527f41697264726f70206e6f7420616c6c6f776564000000000000000000000000006104a052610480816104e00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06104c052806004016104dcfd5b6002546104805261048051602435808201828110612a36579050905060025560406104406104a05e6104405160243580607f1c612a365780820180600f0b8118612a365790509050610440526104205161046051808281188284110218905090506104605260036103e0516020525f5260405f20610440518155610460516001820155506103e05160405260406104a060605e604061044060a05e61059161201f565b6020612a7c5f395f516323b872dd6104e052610400516105005230610520526024356105405260206104e060646104fc5f855af16105d1573d5f5f3e3d5ffd5b3d602081183d6020100218806104e00161050011612a36576104e0518060011c612a3657610560525061056090505115612a3657610460516103e0517f4566dfc29f6f11d13a418c26a02bef7c28bae749d4de47e4e6a7cddea6730d596024356104e052600461050052426105205260606104e0a37f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c610480516104e05261048051602435808201828110612a3657905090506105005260406104e0a15f5f5d005b6328d09d478118611c1757604436103417612a36576004358060a01c612a365760405260076040516020525f5260405f20602435633b9aca00811015612a365760021b8101905080546060526001810154608052600281015460a052600381015460c0525060806060f35b63adc63589811861073f57602436103417612a36576004358060a01c612a365760405260036040516020525f5260405f206001810190505460605260206060f35b63900cf0cf8118611c175734612a365760065460405260206040f35b62fdd58e81186108cf57604436103417612a3657602435610140525b6004358060a01c612a3657610120525f610160524261014051186107ae576008610120516020525f5260405f2054610160526107dd565b604061012060405e6008610120516020525f5260405f20546080526107d4610180611c1b565b61018051610160525b610160516107f4575f6101805260206101806108cd565b6007610120516020525f5260405f2061016051633b9aca00811015612a365760021b8101905080546101805260018101546101a05260028101546101c05260038101546101e05250610180516101a051610140516101c051808203828111612a36579050905080607f1c612a365780820280600f0b8118612a36579050905080820380600f0b8118612a365790509050610180527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61018051136108b8575f610180525b610180515f8112612a36576102005260206102005bf35b63eb1b68ad8118611c1757602436103417612a36576004358060a01c612a36576040526001543318612a36576040515f557f69d78e38a01985fbb1462961809b4b2d65531bc93b2b94037f3334b82ca4a75660405160605260206060a1005b634ee2cd7e8118610beb57604436103417612a36576004358060a01c612a3657610120524360243511612a3657610120516040526024356060526008610120516020525f5260405f2054608052610986610160611cd0565b61016051610140526007610120516020525f5260405f2061014051633b9aca00811015612a365760021b8101905080546101605260018101546101805260028101546101a05260038101546101c052506006546101e0526024356040526101e0516060526109f5610220611d85565b6102205161020052610200516c01431e0fae6d7217caa0000000811015612a365760021b600a01805461022052600181015461024052600281015461026052600381015461028052506040366102a0376101e0516102005110610a85574361028051808203828111612a3657905090506102a0524261026051808203828111612a3657905090506102c052610b08565b6102005160018101818110612a365790506c01431e0fae6d7217caa0000000811015612a365760021b600a0180546102e052600181015461030052600281015461032052600381015461034052506103405161028051808203828111612a3657905090506102a0526103205161026051808203828111612a3657905090506102c0525b610260516102e0526102a05115610b6e576102e0516102c05160243561028051808203828111612a365790509050808202811583838304141715612a3657905090506102a0518015612a365780820490509050808201828110612a3657905090506102e0525b61016051610180516102e0516101a051808203828111612a36579050905080607f1c612a365780820280600f0b8118612a36579050905080820380600f0b8118612a365790509050610160525f610160511215610bd4575f610300526020610300610be9565b610160515f8112612a36576103005260206103005bf35b63d1febfb98118611c1757602436103417612a36576004356c01431e0fae6d7217caa0000000811015612a365760021b600a01805460405260018101546060526002810154608052600381015460a0525060806040f35b63bd85b0398118610d1557602436103417612a36576004356101c0525b5f6101e052426101c05118610c7a576006546101e052610c9b565b6101c051604052600654606052610c92610200611e30565b610200516101e0525b6101e051610cb2575f610200526020610200610d13565b6101e0516c01431e0fae6d7217caa0000000811015612a365760021b600a01805461020052600181015461022052600281015461024052600381015461026052506020608061020060405e6101c05160c052610d0f610280611edb565b6102805bf35b63981b24d08118610f1157602436103417612a36574360043511612a36576006546101c0526004356040526101c051606052610d52610200611d85565b610200516101e0526101e0516c01431e0fae6d7217caa0000000811015612a365760021b600a01805461020052600181015461022052600281015461024052600381015461026052505f610280526101c0516101e05110610e1c57436102605114610ede5760043561026051808203828111612a3657905090504261024051808203828111612a365790509050808202811583838304141715612a3657905090504361026051808203828111612a3657905090508015612a36578082049050905061028052610ede565b6101e05160018101818110612a365790506c01431e0fae6d7217caa0000000811015612a365760021b600a0180546102a05260018101546102c05260028101546102e05260038101546103005250610300516102605114610ede5760043561026051808203828111612a3657905090506102e05161024051808203828111612a365790509050808202811583838304141715612a3657905090506103005161026051808203828111612a3657905090508015612a365780820490509050610280525b6020608061020060405e6102405161028051808201828110612a36579050905060c052610f0c6102a0611edb565b6102a0f35b63cbf9fe5f8118611c1757602436103417612a36576004358060a01c612a365760405260036040516020525f5260405f20805460605260018101546080525060406060f35b63c2c4c5c18118611c175734612a365760a036604037610f7461201f565b005b6365fc3873811861120157604436103417612a36575f5c600114612a365760015f5d610fa36106006126ad565b610600516105e0526105e051604052610fba612774565b60243562093a808104905062093a8081028162093a80820418612a365790506106005260036105e0516020525f5260405f208054610620526001810154610640525060043515612a3657610620511561108a576020806106c0526019610660527f5769746864726177206f6c6420746f6b656e732066697273740000000000000061068052610660816106c00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06106a052806004016106bcfd5b426106005111611136576020806106e0526026610660527f43616e206f6e6c79206c6f636b20756e74696c2074696d6520696e2074686520610680527f66757475726500000000000000000000000000000000000000000000000000006106a052610660816106e00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06106c052806004016106dcfd5b426301e133808101818110612a365790506106005111156111ce576020806106c052601d610660527f566f74696e67206c6f636b2063616e20626520312079656172206d617800000061068052610660816106c00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06106a052806004016106bcfd5b6105e0516103e05260043561040052610600516104205260406106206104405e6001610480526111fc612881565b5f5f5d005b6384782ac88118611c1757604436103417612a36576004358060a01c612a36576040526024358060a01c612a365760605260016040516020525f5260405f20806060516020525f5260405f2090505c60805260206080f35b634957677c8118611c1757602436103417612a36575f5c600114612a365760015f5d6112866106006126ad565b610600516105e0526105e05160405261129d612774565b60036105e0516020525f5260405f208054610600526001810154610620525060043515612a3657600161060051121561134d576020806106a0526016610640527f4e6f206578697374696e67206c6f636b20666f756e640000000000000000000061066052610640816106a00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a0610680528060040161069cfd5b4261062051116113f9576020806106c0526024610640527f43616e6e6f742061646420746f2065787069726564206c6f636b2e2057697468610660527f647261770000000000000000000000000000000000000000000000000000000061068052610640816106c00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06106a052806004016106bcfd5b6105e0516103e052600435610400525f6104205260406106006104405e600261048052611424612881565b5f5f5d005b63eff7a6128118611c1757602436103417612a36575f5c600114612a365760015f5d6114566106006126ad565b610600516105e0526105e05160405261146d612774565b60036105e0516020525f5260405f208054610600526001810154610620525060043562093a808104905062093a8081028162093a80820418612a3657905061064052426106205111611536576020806106c052600c610660527f4c6f636b2065787069726564000000000000000000000000000000000000000061068052610660816106c00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06106a052806004016106bcfd5b60016106005112156115bf576020806106c0526011610660527f4e6f7468696e67206973206c6f636b656400000000000000000000000000000061068052610660816106c00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06106a052806004016106bcfd5b610620516106405111611649576020806106c052601f610660527f43616e206f6e6c7920696e637265617365206c6f636b206475726174696f6e0061068052610660816106c00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06106a052806004016106bcfd5b426301e133808101818110612a365790506106405111156116e1576020806106c052601d610660527f566f74696e67206c6f636b2063616e20626520312079656172206d617800000061068052610660816106c00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06106a052806004016106bcfd5b6105e0516103e0525f61040052610640516104205260406106006104405e60036104805261170d612881565b5f5f5d005b633ccfd60b8118611c175734612a36575f5c600114612a365760015f5d61173a6104006126ad565b610400516103e05260036103e0516020525f5260405f208054610400526001810154610420525061042051421015611780576c050c783eb9b5c85f2a8000000a54611783565b60015b611829576020806104c052603c610440527f546865206c6f636b206469646e277420657870697265206f722074686520756e610460527f6c6f636b206675736520686173206e6f74206265656e206275726e740000000061048052610440816104c00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06104a052806004016104bcfd5b610400515f8112612a36576104405260406104006104605e5f610420525f6104005260036103e0516020525f5260405f20610400518155610420516001820155506002546104a0526104a05161044051808203828111612a3657905090506002556103e051604052604061046060605e604061040060a05e6118a961201f565b6020612a7c5f395f5163a9059cbb6104c0526103e0516104e052610440516105005260206104c060446104dc5f855af16118e5573d5f5f3e3d5ffd5b3d602081183d6020100218806104c0016104e011612a36576104c0518060011c612a3657610520525061052090505115612a36576103e0517ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568610440516104c052426104e05260406104c0a27f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c6104a0516104c0526104a05161044051808203828111612a3657905090506104e05260406104c0a15f5f5d005b632280c1318118611c1757602436103417612a36576004358060a01c612a3657610100526119ce6101406126ad565b610140516101205260016001610120516020525f5260405f2080610100516020525f5260405f2090505d61010051610120517fde36889f835a400f5f83816b33e0db11b37fbc69cea08db9877f7f86b5b383045f610140a3005b6357f901e28118611c1757602436103417612a36576004358060a01c612a36576040526001543318612a36576040516004556040517f4f81a6dc9d272c26f62c023b68dad221344ba9b3f4c45536021c13f81a3d984a5f6060a2005b638e5b490f8118611c175734612a36576001543318612a36576004546040526040516005556040517f5cbaa8f81c60615da12ac3c0a38416550eb1c316758654aa707a3062c7b5fe7e5f6060a2005b63d6ecc5508118611c175734612a36576001543318612a365760016c050c783eb9b5c85f2a8000000a557fec2f25d7843f1f9cc8328c327fb0b7184fbba070875a4e644ee18cb3ae39100e5f6040a1005b63e67192878118611c175734612a36575f5460405260206040f35b63f851a4408118611b5b5734612a365760015460405260206040f35b63010ae7578118611c1757602436103417612a36576004358060a01c612a365760405260086040516020525f5260405f205460605260206060f35b63047fc9aa8118611c175734612a365760025460405260206040f35b638ff36fd18118611c175734612a365760045460405260206040f35b637175d4f78118611c175734612a365760055460405260206040f35b63711974848118611c1757602436103417612a365760096004356020525f5260405f205460405260206040f35b5f5ffd5b5f60a05260805160c0525f6080905b8060e05260c05160a0511015611cc65760a05160c051808201828110612a36579050905060018101818110612a365790508060011c90506101005260605160076040516020525f5260405f2061010051633b9aca00811015612a365760021b81019050600281019050541115611cb3576101005160018103818111612a3657905060c052611cbb565b6101005160a0525b600101818118611c2a575b505060a051815250565b5f60a05260805160c0525f6080905b8060e05260c05160a0511015611d7b5760a05160c051808201828110612a36579050905060018101818110612a365790508060011c90506101005260605160076040516020525f5260405f2061010051633b9aca00811015612a365760021b81019050600381019050541115611d68576101005160018103818111612a3657905060c052611d70565b6101005160a0525b600101818118611cdf575b505060a051815250565b5f60805260605160a0525f6080905b8060c05260a0516080511015611e265760805160a051808201828110612a36579050905060018101818110612a365790508060011c905060e05260405160e0516c01431e0fae6d7217caa0000000811015612a365760021b600a01600381019050541115611e145760e05160018103818111612a3657905060a052611e1b565b60e0516080525b600101818118611d94575b5050608051815250565b5f60805260605160a0525f6080905b8060c05260a0516080511015611ed15760805160a051808201828110612a36579050905060018101818110612a365790508060011c905060e05260405160e0516c01431e0fae6d7217caa0000000811015612a365760021b600a01600281019050541115611ebf5760e05160018103818111612a3657905060a052611ec6565b60e0516080525b600101818118611e3f575b5050608051815250565b6080604060e05e6101205162093a808104905062093a8081028162093a80820418612a36579050610160525f60ff905b80610180526101605162093a808101818110612a36579050610160525f6101a05260c0516101605111611f51576009610160516020525f5260405f20546101a052611f59565b60c051610160525b60e051610100516101605161012051808203828111612a36579050905080607f1c612a365780820280600f0b8118612a36579050905080820380600f0b8118612a36579050905060e05260c051610160511815611fe057610100516101a05180820180600f0b8118612a365790509050610100526101605161012052600101818118611f0b575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60e05113612010575f60e0525b60e0515f8112612a3657815250565b6101403660e0376006546102205260405115612179574260805111612044575f61204c565b600160605112155b156120b3576060516301e13380607f1c612a36576301e133808015612a365780820580600f0b8118612a365790509050610100526101005160805142808203828111612a36579050905080607f1c612a365780820280600f0b8118612a36579050905060e0525b4260c051116120c2575f6120ca565b600160a05112155b156121325760a0516301e13380607f1c612a36576301e133808015612a365780820580600f0b8118612a365790509050610180526101805160c05142808203828111612a36579050905080607f1c612a365780820280600f0b8118612a365790509050610160525b60096080516020525f5260405f20546101e05260c051156121795760805160c05118612165576101e05161020052612179565b600960c0516020525f5260405f2054610200525b604036610240374261028052436102a05261022051156121d557610220516c01431e0fae6d7217caa0000000811015612a365760021b600a0180546102405260018101546102605260028101546102805260038101546102a052505b610280516102c05260806102406102e05e5f610360526102805142111561224c57436102a051808203828111612a365790509050670de0b6b3a7640000810281670de0b6b3a7640000820418612a365790504261028051808203828111612a3657905090508015612a365780820490509050610360525b6102c05162093a808104905062093a8081028162093a80820418612a36579050610380525f60ff905b806103a0526103805162093a808101818110612a36579050610380525f6103c0524261038051116122b9576009610380516020525f5260405f20546103c0526122bf565b42610380525b6102405161026051610380516102c051808203828111612a36579050905080607f1c612a365780820280600f0b8118612a36579050905080820380600f0b8118612a36579050905061024052610260516103c05180820180600f0b8118612a365790509050610260527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102405113612358575f610240525b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102605113612388575f610260525b610380516102c052610380516102805261034051610360516103805161032051808203828111612a365790509050808202811583838304141715612a365790509050670de0b6b3a764000081049050808201828110612a3657905090506102a0526102205160018101818110612a365790506102205242610380511861241257436102a05261245e565b610220516c01431e0fae6d7217caa0000000811015612a365760021b600a016102405181556102605160018201556102805160028201556102a051600382015550600101818118612275575b505061022051600655604051156125325761026051610180516101005180820380600f0b8118612a36579050905080820180600f0b8118612a36579050905061026052610240516101605160e05180820380600f0b8118612a36579050905080820180600f0b8118612a365790509050610240527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102605113612502575f610260525b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102405113612532575f610240525b610220516c01431e0fae6d7217caa0000000811015612a365760021b600a016102405181556102605160018201556102805160028201556102a051600382015550604051156126ab574260805111156125df576101e0516101005180820180600f0b8118612a3657905090506101e05260805160c051186125cb576101e0516101805180820380600f0b8118612a3657905090506101e0525b6101e05160096080516020525f5260405f20555b4260c05111156126265760805160c051111561262657610200516101805180820380600f0b8118612a3657905090506102005261020051600960c0516020525f5260405f20555b60086040516020525f5260405f205460018101818110612a365790506103a0526103a05160086040516020525f5260405f2055426101a052436101c05260076040516020525f5260405f206103a051633b9aca00811015612a365760021b810190506101605181556101805160018201556101a05160028201556101c0516003820155505b565b336e2fd5aeb385d324b580fca7c83823a081186126cb5760016126de565b6dd9ecebf3c23529de49815dac1c4c8118155b90506126ed5733815250612772565b335a5f60a05260a050602060e060a05160c08585fa90509050612712573d5f5f3e3d5ffd5b3d602081183d602010021860c05260c06020815101808260605e50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6020606051031360011615612a36575f806080015190508060a01c612a36578152505b565b326040511461287f57600554606052606051156127e35760605163c23697a860805260405160a052602060806024609c5f855af16127b4573d5f5f3e3d5ffd5b3d602081183d60201002188060800160a011612a36576080518060011c612a365760c0525060c090505161287f575b6020806101005260256080527f536d61727420636f6e7472616374206465706f7369746f7273206e6f7420616c60a0527f6c6f77656400000000000000000000000000000000000000000000000000000060c0526080816101000160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a060e0528060040160fcfd5b565b60406104406104a05e6002546104e0526104e05161040051808201828110612a36579050905060025560406104a06105005e6104a0516104005180607f1c612a365780820180600f0b8118612a3657905090506104a05261042051156128ea57610420516104c0525b60036103e0516020525f5260405f206104a05181556104c0516001820155506103e051604052604061050060605e60406104a060a05e61292861201f565b61040051156129a7576020612a7c5f395f516323b872dd610540526103e051610560523061058052610400516105a0526020610540606461055c5f855af1612972573d5f5f3e3d5ffd5b3d602081183d6020100218806105400161056011612a3657610540518060011c612a36576105c052506105c090505115612a36575b6104c0516103e0517f4566dfc29f6f11d13a418c26a02bef7c28bae749d4de47e4e6a7cddea6730d596104005161054052610480516105605242610580526060610540a37f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c6104e051610540526104e05161040051808201828110612a365790509050610560526040610540a1565b5f80fd17121bb21c171a841ad31bea06fe1429092e0f560018075b1b241c17199f1c171c171b3f00f101650f760c421b961a2801471c171bce1c170036021512591c171c1784192a7c81184218e0a1657679706572830004000016000000000000000000000000000000c396558ffbab5ea628f39658bdf61345b300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000009a8fee232dcf73060af348a1b62cdb0a19852d1300000000000000000000000000000041cb569fdbac52b95b91c52263cea3f3ce0000000000000000000000000000000000000000000000000000000000000013566f746520457363726f7765642042554e4e49000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007766542554e4e4900000000000000000000000000000000000000000000000000
Deployed Bytecode
0x5f3560e01c60026021820660011b612a3a01601e395f51565b63fc0c546a8118611c175734612a36576020612a7c60403960206040f35b6306fdde03811861008c5734612a36576020806040528060400160206020612a9c5f395f510180612a9c8339508051806020830101601f825f03163682375050601f19601f825160200101169050810190506040f35b6318160ddd81186100a65734612a3657426101c052610c5f565b63a3ce42d08118611c175734612a36575f543318612a3657336001555f5f557f71614071b88dee5e0b2ae578a9dd7b2ebbe9ae832ba419dc0242cd065a290b6c3360405260206040a1005b6395d89b418118611c175734612a36576020806040528060400160206020612afc5f395f510180612afc8339508051806020830101601f825f03163682375050601f19601f825160200101169050810190506040f35b63313ce5678118611c175734612a36576020612b3c60403960206040f35b637c74a17481186101ce57602436103417612a36576004358060a01c612a365760405260086040516020525f5260405f205460605260076040516020525f5260405f20606051633b9aca00811015612a365760021b810190506001810190505460805260206080f35b6370a0823181186101ed57602436103417612a36574261014052610777565b636cf492d38118611c175734612a36576c050c783eb9b5c85f2a8000000a5460405260206040f35b63da020a18811861026c57604436103417612a36576004358060a01c612a365760405260076040516020525f5260405f20602435633b9aca00811015612a365760021b810190506002810190505460605260206060f35b63e1bc2967811861069357606436103417612a36576004358060a01c612a36576103e0525f5c600114612a365760015f5d6102a86104206126ad565b61042051610400526103e0516040526102bf612774565b60443562093a808104905062093a8081028162093a80820418612a365790506104205260036103e0516020525f5260405f208054610440526001810154610460525060243515612a36574261042051116103b557602080610500526026610480527f43616e206f6e6c79206c6f636b20756e74696c2074696d6520696e20746865206104a0527f66757475726500000000000000000000000000000000000000000000000000006104c052610480816105000160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06104e052806004016104fcfd5b426301e133808101818110612a3657905061042051111561044d576020806104e052601d610480527f566f74696e67206c6f636b2063616e20626520312079656172206d61780000006104a052610480816104e00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06104c052806004016104dcfd5b60016103e0516020525f5260405f2080610400516020525f5260405f2090505c6104ee576020806104e0526013610480527f41697264726f70206e6f7420616c6c6f776564000000000000000000000000006104a052610480816104e00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06104c052806004016104dcfd5b6002546104805261048051602435808201828110612a36579050905060025560406104406104a05e6104405160243580607f1c612a365780820180600f0b8118612a365790509050610440526104205161046051808281188284110218905090506104605260036103e0516020525f5260405f20610440518155610460516001820155506103e05160405260406104a060605e604061044060a05e61059161201f565b6020612a7c5f395f516323b872dd6104e052610400516105005230610520526024356105405260206104e060646104fc5f855af16105d1573d5f5f3e3d5ffd5b3d602081183d6020100218806104e00161050011612a36576104e0518060011c612a3657610560525061056090505115612a3657610460516103e0517f4566dfc29f6f11d13a418c26a02bef7c28bae749d4de47e4e6a7cddea6730d596024356104e052600461050052426105205260606104e0a37f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c610480516104e05261048051602435808201828110612a3657905090506105005260406104e0a15f5f5d005b6328d09d478118611c1757604436103417612a36576004358060a01c612a365760405260076040516020525f5260405f20602435633b9aca00811015612a365760021b8101905080546060526001810154608052600281015460a052600381015460c0525060806060f35b63adc63589811861073f57602436103417612a36576004358060a01c612a365760405260036040516020525f5260405f206001810190505460605260206060f35b63900cf0cf8118611c175734612a365760065460405260206040f35b62fdd58e81186108cf57604436103417612a3657602435610140525b6004358060a01c612a3657610120525f610160524261014051186107ae576008610120516020525f5260405f2054610160526107dd565b604061012060405e6008610120516020525f5260405f20546080526107d4610180611c1b565b61018051610160525b610160516107f4575f6101805260206101806108cd565b6007610120516020525f5260405f2061016051633b9aca00811015612a365760021b8101905080546101805260018101546101a05260028101546101c05260038101546101e05250610180516101a051610140516101c051808203828111612a36579050905080607f1c612a365780820280600f0b8118612a36579050905080820380600f0b8118612a365790509050610180527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61018051136108b8575f610180525b610180515f8112612a36576102005260206102005bf35b63eb1b68ad8118611c1757602436103417612a36576004358060a01c612a36576040526001543318612a36576040515f557f69d78e38a01985fbb1462961809b4b2d65531bc93b2b94037f3334b82ca4a75660405160605260206060a1005b634ee2cd7e8118610beb57604436103417612a36576004358060a01c612a3657610120524360243511612a3657610120516040526024356060526008610120516020525f5260405f2054608052610986610160611cd0565b61016051610140526007610120516020525f5260405f2061014051633b9aca00811015612a365760021b8101905080546101605260018101546101805260028101546101a05260038101546101c052506006546101e0526024356040526101e0516060526109f5610220611d85565b6102205161020052610200516c01431e0fae6d7217caa0000000811015612a365760021b600a01805461022052600181015461024052600281015461026052600381015461028052506040366102a0376101e0516102005110610a85574361028051808203828111612a3657905090506102a0524261026051808203828111612a3657905090506102c052610b08565b6102005160018101818110612a365790506c01431e0fae6d7217caa0000000811015612a365760021b600a0180546102e052600181015461030052600281015461032052600381015461034052506103405161028051808203828111612a3657905090506102a0526103205161026051808203828111612a3657905090506102c0525b610260516102e0526102a05115610b6e576102e0516102c05160243561028051808203828111612a365790509050808202811583838304141715612a3657905090506102a0518015612a365780820490509050808201828110612a3657905090506102e0525b61016051610180516102e0516101a051808203828111612a36579050905080607f1c612a365780820280600f0b8118612a36579050905080820380600f0b8118612a365790509050610160525f610160511215610bd4575f610300526020610300610be9565b610160515f8112612a36576103005260206103005bf35b63d1febfb98118611c1757602436103417612a36576004356c01431e0fae6d7217caa0000000811015612a365760021b600a01805460405260018101546060526002810154608052600381015460a0525060806040f35b63bd85b0398118610d1557602436103417612a36576004356101c0525b5f6101e052426101c05118610c7a576006546101e052610c9b565b6101c051604052600654606052610c92610200611e30565b610200516101e0525b6101e051610cb2575f610200526020610200610d13565b6101e0516c01431e0fae6d7217caa0000000811015612a365760021b600a01805461020052600181015461022052600281015461024052600381015461026052506020608061020060405e6101c05160c052610d0f610280611edb565b6102805bf35b63981b24d08118610f1157602436103417612a36574360043511612a36576006546101c0526004356040526101c051606052610d52610200611d85565b610200516101e0526101e0516c01431e0fae6d7217caa0000000811015612a365760021b600a01805461020052600181015461022052600281015461024052600381015461026052505f610280526101c0516101e05110610e1c57436102605114610ede5760043561026051808203828111612a3657905090504261024051808203828111612a365790509050808202811583838304141715612a3657905090504361026051808203828111612a3657905090508015612a36578082049050905061028052610ede565b6101e05160018101818110612a365790506c01431e0fae6d7217caa0000000811015612a365760021b600a0180546102a05260018101546102c05260028101546102e05260038101546103005250610300516102605114610ede5760043561026051808203828111612a3657905090506102e05161024051808203828111612a365790509050808202811583838304141715612a3657905090506103005161026051808203828111612a3657905090508015612a365780820490509050610280525b6020608061020060405e6102405161028051808201828110612a36579050905060c052610f0c6102a0611edb565b6102a0f35b63cbf9fe5f8118611c1757602436103417612a36576004358060a01c612a365760405260036040516020525f5260405f20805460605260018101546080525060406060f35b63c2c4c5c18118611c175734612a365760a036604037610f7461201f565b005b6365fc3873811861120157604436103417612a36575f5c600114612a365760015f5d610fa36106006126ad565b610600516105e0526105e051604052610fba612774565b60243562093a808104905062093a8081028162093a80820418612a365790506106005260036105e0516020525f5260405f208054610620526001810154610640525060043515612a3657610620511561108a576020806106c0526019610660527f5769746864726177206f6c6420746f6b656e732066697273740000000000000061068052610660816106c00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06106a052806004016106bcfd5b426106005111611136576020806106e0526026610660527f43616e206f6e6c79206c6f636b20756e74696c2074696d6520696e2074686520610680527f66757475726500000000000000000000000000000000000000000000000000006106a052610660816106e00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06106c052806004016106dcfd5b426301e133808101818110612a365790506106005111156111ce576020806106c052601d610660527f566f74696e67206c6f636b2063616e20626520312079656172206d617800000061068052610660816106c00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06106a052806004016106bcfd5b6105e0516103e05260043561040052610600516104205260406106206104405e6001610480526111fc612881565b5f5f5d005b6384782ac88118611c1757604436103417612a36576004358060a01c612a36576040526024358060a01c612a365760605260016040516020525f5260405f20806060516020525f5260405f2090505c60805260206080f35b634957677c8118611c1757602436103417612a36575f5c600114612a365760015f5d6112866106006126ad565b610600516105e0526105e05160405261129d612774565b60036105e0516020525f5260405f208054610600526001810154610620525060043515612a3657600161060051121561134d576020806106a0526016610640527f4e6f206578697374696e67206c6f636b20666f756e640000000000000000000061066052610640816106a00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a0610680528060040161069cfd5b4261062051116113f9576020806106c0526024610640527f43616e6e6f742061646420746f2065787069726564206c6f636b2e2057697468610660527f647261770000000000000000000000000000000000000000000000000000000061068052610640816106c00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06106a052806004016106bcfd5b6105e0516103e052600435610400525f6104205260406106006104405e600261048052611424612881565b5f5f5d005b63eff7a6128118611c1757602436103417612a36575f5c600114612a365760015f5d6114566106006126ad565b610600516105e0526105e05160405261146d612774565b60036105e0516020525f5260405f208054610600526001810154610620525060043562093a808104905062093a8081028162093a80820418612a3657905061064052426106205111611536576020806106c052600c610660527f4c6f636b2065787069726564000000000000000000000000000000000000000061068052610660816106c00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06106a052806004016106bcfd5b60016106005112156115bf576020806106c0526011610660527f4e6f7468696e67206973206c6f636b656400000000000000000000000000000061068052610660816106c00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06106a052806004016106bcfd5b610620516106405111611649576020806106c052601f610660527f43616e206f6e6c7920696e637265617365206c6f636b206475726174696f6e0061068052610660816106c00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06106a052806004016106bcfd5b426301e133808101818110612a365790506106405111156116e1576020806106c052601d610660527f566f74696e67206c6f636b2063616e20626520312079656172206d617800000061068052610660816106c00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06106a052806004016106bcfd5b6105e0516103e0525f61040052610640516104205260406106006104405e60036104805261170d612881565b5f5f5d005b633ccfd60b8118611c175734612a36575f5c600114612a365760015f5d61173a6104006126ad565b610400516103e05260036103e0516020525f5260405f208054610400526001810154610420525061042051421015611780576c050c783eb9b5c85f2a8000000a54611783565b60015b611829576020806104c052603c610440527f546865206c6f636b206469646e277420657870697265206f722074686520756e610460527f6c6f636b206675736520686173206e6f74206265656e206275726e740000000061048052610440816104c00160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a06104a052806004016104bcfd5b610400515f8112612a36576104405260406104006104605e5f610420525f6104005260036103e0516020525f5260405f20610400518155610420516001820155506002546104a0526104a05161044051808203828111612a3657905090506002556103e051604052604061046060605e604061040060a05e6118a961201f565b6020612a7c5f395f5163a9059cbb6104c0526103e0516104e052610440516105005260206104c060446104dc5f855af16118e5573d5f5f3e3d5ffd5b3d602081183d6020100218806104c0016104e011612a36576104c0518060011c612a3657610520525061052090505115612a36576103e0517ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568610440516104c052426104e05260406104c0a27f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c6104a0516104c0526104a05161044051808203828111612a3657905090506104e05260406104c0a15f5f5d005b632280c1318118611c1757602436103417612a36576004358060a01c612a3657610100526119ce6101406126ad565b610140516101205260016001610120516020525f5260405f2080610100516020525f5260405f2090505d61010051610120517fde36889f835a400f5f83816b33e0db11b37fbc69cea08db9877f7f86b5b383045f610140a3005b6357f901e28118611c1757602436103417612a36576004358060a01c612a36576040526001543318612a36576040516004556040517f4f81a6dc9d272c26f62c023b68dad221344ba9b3f4c45536021c13f81a3d984a5f6060a2005b638e5b490f8118611c175734612a36576001543318612a36576004546040526040516005556040517f5cbaa8f81c60615da12ac3c0a38416550eb1c316758654aa707a3062c7b5fe7e5f6060a2005b63d6ecc5508118611c175734612a36576001543318612a365760016c050c783eb9b5c85f2a8000000a557fec2f25d7843f1f9cc8328c327fb0b7184fbba070875a4e644ee18cb3ae39100e5f6040a1005b63e67192878118611c175734612a36575f5460405260206040f35b63f851a4408118611b5b5734612a365760015460405260206040f35b63010ae7578118611c1757602436103417612a36576004358060a01c612a365760405260086040516020525f5260405f205460605260206060f35b63047fc9aa8118611c175734612a365760025460405260206040f35b638ff36fd18118611c175734612a365760045460405260206040f35b637175d4f78118611c175734612a365760055460405260206040f35b63711974848118611c1757602436103417612a365760096004356020525f5260405f205460405260206040f35b5f5ffd5b5f60a05260805160c0525f6080905b8060e05260c05160a0511015611cc65760a05160c051808201828110612a36579050905060018101818110612a365790508060011c90506101005260605160076040516020525f5260405f2061010051633b9aca00811015612a365760021b81019050600281019050541115611cb3576101005160018103818111612a3657905060c052611cbb565b6101005160a0525b600101818118611c2a575b505060a051815250565b5f60a05260805160c0525f6080905b8060e05260c05160a0511015611d7b5760a05160c051808201828110612a36579050905060018101818110612a365790508060011c90506101005260605160076040516020525f5260405f2061010051633b9aca00811015612a365760021b81019050600381019050541115611d68576101005160018103818111612a3657905060c052611d70565b6101005160a0525b600101818118611cdf575b505060a051815250565b5f60805260605160a0525f6080905b8060c05260a0516080511015611e265760805160a051808201828110612a36579050905060018101818110612a365790508060011c905060e05260405160e0516c01431e0fae6d7217caa0000000811015612a365760021b600a01600381019050541115611e145760e05160018103818111612a3657905060a052611e1b565b60e0516080525b600101818118611d94575b5050608051815250565b5f60805260605160a0525f6080905b8060c05260a0516080511015611ed15760805160a051808201828110612a36579050905060018101818110612a365790508060011c905060e05260405160e0516c01431e0fae6d7217caa0000000811015612a365760021b600a01600281019050541115611ebf5760e05160018103818111612a3657905060a052611ec6565b60e0516080525b600101818118611e3f575b5050608051815250565b6080604060e05e6101205162093a808104905062093a8081028162093a80820418612a36579050610160525f60ff905b80610180526101605162093a808101818110612a36579050610160525f6101a05260c0516101605111611f51576009610160516020525f5260405f20546101a052611f59565b60c051610160525b60e051610100516101605161012051808203828111612a36579050905080607f1c612a365780820280600f0b8118612a36579050905080820380600f0b8118612a36579050905060e05260c051610160511815611fe057610100516101a05180820180600f0b8118612a365790509050610100526101605161012052600101818118611f0b575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60e05113612010575f60e0525b60e0515f8112612a3657815250565b6101403660e0376006546102205260405115612179574260805111612044575f61204c565b600160605112155b156120b3576060516301e13380607f1c612a36576301e133808015612a365780820580600f0b8118612a365790509050610100526101005160805142808203828111612a36579050905080607f1c612a365780820280600f0b8118612a36579050905060e0525b4260c051116120c2575f6120ca565b600160a05112155b156121325760a0516301e13380607f1c612a36576301e133808015612a365780820580600f0b8118612a365790509050610180526101805160c05142808203828111612a36579050905080607f1c612a365780820280600f0b8118612a365790509050610160525b60096080516020525f5260405f20546101e05260c051156121795760805160c05118612165576101e05161020052612179565b600960c0516020525f5260405f2054610200525b604036610240374261028052436102a05261022051156121d557610220516c01431e0fae6d7217caa0000000811015612a365760021b600a0180546102405260018101546102605260028101546102805260038101546102a052505b610280516102c05260806102406102e05e5f610360526102805142111561224c57436102a051808203828111612a365790509050670de0b6b3a7640000810281670de0b6b3a7640000820418612a365790504261028051808203828111612a3657905090508015612a365780820490509050610360525b6102c05162093a808104905062093a8081028162093a80820418612a36579050610380525f60ff905b806103a0526103805162093a808101818110612a36579050610380525f6103c0524261038051116122b9576009610380516020525f5260405f20546103c0526122bf565b42610380525b6102405161026051610380516102c051808203828111612a36579050905080607f1c612a365780820280600f0b8118612a36579050905080820380600f0b8118612a36579050905061024052610260516103c05180820180600f0b8118612a365790509050610260527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102405113612358575f610240525b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102605113612388575f610260525b610380516102c052610380516102805261034051610360516103805161032051808203828111612a365790509050808202811583838304141715612a365790509050670de0b6b3a764000081049050808201828110612a3657905090506102a0526102205160018101818110612a365790506102205242610380511861241257436102a05261245e565b610220516c01431e0fae6d7217caa0000000811015612a365760021b600a016102405181556102605160018201556102805160028201556102a051600382015550600101818118612275575b505061022051600655604051156125325761026051610180516101005180820380600f0b8118612a36579050905080820180600f0b8118612a36579050905061026052610240516101605160e05180820380600f0b8118612a36579050905080820180600f0b8118612a365790509050610240527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102605113612502575f610260525b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102405113612532575f610240525b610220516c01431e0fae6d7217caa0000000811015612a365760021b600a016102405181556102605160018201556102805160028201556102a051600382015550604051156126ab574260805111156125df576101e0516101005180820180600f0b8118612a3657905090506101e05260805160c051186125cb576101e0516101805180820380600f0b8118612a3657905090506101e0525b6101e05160096080516020525f5260405f20555b4260c05111156126265760805160c051111561262657610200516101805180820380600f0b8118612a3657905090506102005261020051600960c0516020525f5260405f20555b60086040516020525f5260405f205460018101818110612a365790506103a0526103a05160086040516020525f5260405f2055426101a052436101c05260076040516020525f5260405f206103a051633b9aca00811015612a365760021b810190506101605181556101805160018201556101a05160028201556101c0516003820155505b565b336e2fd5aeb385d324b580fca7c83823a081186126cb5760016126de565b6dd9ecebf3c23529de49815dac1c4c8118155b90506126ed5733815250612772565b335a5f60a05260a050602060e060a05160c08585fa90509050612712573d5f5f3e3d5ffd5b3d602081183d602010021860c05260c06020815101808260605e50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6020606051031360011615612a36575f806080015190508060a01c612a36578152505b565b326040511461287f57600554606052606051156127e35760605163c23697a860805260405160a052602060806024609c5f855af16127b4573d5f5f3e3d5ffd5b3d602081183d60201002188060800160a011612a36576080518060011c612a365760c0525060c090505161287f575b6020806101005260256080527f536d61727420636f6e7472616374206465706f7369746f7273206e6f7420616c60a0527f6c6f77656400000000000000000000000000000000000000000000000000000060c0526080816101000160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506308c379a060e0528060040160fcfd5b565b60406104406104a05e6002546104e0526104e05161040051808201828110612a36579050905060025560406104a06105005e6104a0516104005180607f1c612a365780820180600f0b8118612a3657905090506104a05261042051156128ea57610420516104c0525b60036103e0516020525f5260405f206104a05181556104c0516001820155506103e051604052604061050060605e60406104a060a05e61292861201f565b61040051156129a7576020612a7c5f395f516323b872dd610540526103e051610560523061058052610400516105a0526020610540606461055c5f855af1612972573d5f5f3e3d5ffd5b3d602081183d6020100218806105400161056011612a3657610540518060011c612a36576105c052506105c090505115612a36575b6104c0516103e0517f4566dfc29f6f11d13a418c26a02bef7c28bae749d4de47e4e6a7cddea6730d596104005161054052610480516105605242610580526060610540a37f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c6104e051610540526104e05161040051808201828110612a365790509050610560526040610540a1565b5f80fd17121bb21c171a841ad31bea06fe1429092e0f560018075b1b241c17199f1c171c171b3f00f101650f760c421b961a2801471c171bce1c170036021512591c171c17000000000000000000000000000000c396558ffbab5ea628f39658bdf61345b30000000000000000000000000000000000000000000000000000000000000013566f746520457363726f7765642042554e4e490000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007766542554e4e49000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000c396558ffbab5ea628f39658bdf61345b300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000009a8fee232dcf73060af348a1b62cdb0a19852d1300000000000000000000000000000041cb569fdbac52b95b91c52263cea3f3ce0000000000000000000000000000000000000000000000000000000000000013566f746520457363726f7765642042554e4e49000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007766542554e4e4900000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : token_addr (address): 0x000000C396558ffbAB5Ea628f39658Bdf61345b3
Arg [1] : _name (string): Vote Escrowed BUNNI
Arg [2] : _symbol (string): veBUNNI
Arg [3] : _admin (address): 0x9a8FEe232DCF73060Af348a1B62Cdb0a19852d13
Arg [4] : _smart_wallet_checker (address): 0x00000041Cb569fdBAC52b95B91c52263cea3f3cE
-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 000000000000000000000000000000c396558ffbab5ea628f39658bdf61345b3
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [3] : 0000000000000000000000009a8fee232dcf73060af348a1b62cdb0a19852d13
Arg [4] : 00000000000000000000000000000041cb569fdbac52b95b91c52263cea3f3ce
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000013
Arg [6] : 566f746520457363726f7765642042554e4e4900000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000007
Arg [8] : 766542554e4e4900000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.
Add Token to MetaMask (Web3)