ETH Price: $1,972.43 (+0.19%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Infinite_lock_to...239599062025-12-07 8:56:5976 days ago1765097819IN
0x58B63e10...D7b376928
0 ETH0.000023920.13444569
Create_lock239598462025-12-07 8:44:5976 days ago1765097099IN
0x58B63e10...D7b376928
0 ETH0.000035980.08652705

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Method Block
From
To
0x602d3d81233709582025-09-15 20:47:47159 days ago1757969267  Contract Creation0 ETH
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Minimal Proxy Contract for 0x60043a545e22424e73a2debb98f8cd4361fe3da0

Contract Name:
Cliff Escrow

Compiler Version
vyper:0.4.3

Optimization Enabled:
Yes

Other Settings:
default evmVersion, None license

Contract Source Code (Vyper Json-Input format)

File 1 of 1 : CliffEscrow.vy
# @version 0.4.3
"""
@title Cliff Escrow
@author Yield Basis
@license MIT
@notice Limits what one can do with received tokens before the cliff time is over
"""
from ethereum.ercs import IERC20


interface VotingEscrow:
    def create_lock(_value: uint256, _unlock_time: uint256): nonpayable
    def increase_amount(_value: uint256): nonpayable
    def increase_unlock_time(_unlock_time: uint256): nonpayable
    def withdraw(): nonpayable
    def transferFrom(owner: address, to: address, token_id: uint256): nonpayable
    def infinite_lock_toggle(): nonpayable

interface GaugeController:
    def vote_for_gauge_weights(_gauge_addrs: DynArray[address, 50], _user_weights: DynArray[uint256, 50]): nonpayable

interface AragonDAO:
    def vote(_proposalId: uint256, _voteOption: uint8, _tryEarlyExecution: bool): nonpayable


event TokenRecovered:
    token: indexed(address)
    to: address
    amount: uint256


GC: public(immutable(GaugeController))
YB: public(immutable(IERC20))
VE: public(immutable(VotingEscrow))

unlock_time: public(uint256)
recipient: public(address)


@deploy
def __init__(token: IERC20, ve: VotingEscrow, gc: GaugeController):
    """
    @param token Token to be distributed by the CliffEscrow
    @param ve VotingEscrow (ve-locker)
    @param gc GaugeController
    """
    YB = token
    VE = ve
    GC = gc
    self.recipient = self


@external
def initialize(recipient: address, unlock_time: uint256) -> bool:
    """
    @notice Initialize an instance created by a factory contract
    @param recipient Recipient of the tokens (one per contract!)
    @param unlock_time When all the tokens can be released (cliff time)
    """
    assert recipient != empty(address), "Empty recipient"
    assert self.recipient == empty(address), "Already initialized"
    assert unlock_time > block.timestamp
    self.recipient = recipient
    self.unlock_time = unlock_time
    extcall YB.approve(VE.address, max_value(uint256))
    return True


@internal
def _access():
    assert msg.sender == self.recipient, "Not authorized"


@internal
def _cliff():
    assert block.timestamp >= self.unlock_time, "Cliff still applies"


@external
@nonreentrant
def create_lock(_value: uint256, _unlock_time: uint256):
    """
    @notice Create a ve-lock while affected by the cliff
    @param _value Amount to ve-lock
    @param _unlock_time Time for ve-lock to end
    """
    self._access()
    extcall VE.create_lock(_value, _unlock_time)


@external
@nonreentrant
def increase_amount(_value: uint256):
    """
    @notice Increase amount in the ve-lock
    @param _value Number of tokens to add to ve-lock
    """
    self._access()
    extcall VE.increase_amount(_value)


@external
@nonreentrant
def increase_unlock_time(_unlock_time: uint256):
    """
    @notice Increase the duration of ve-lock
    @param _unlock_time New unlock timestamp (seconds)
    """
    self._access()
    extcall VE.increase_unlock_time(_unlock_time)


@external
@nonreentrant
def withdraw():
    """
    @notice Withdraw all tokens from expired ve-lock back to the CliffEscrow contract
    """
    self._access()
    extcall VE.withdraw()


@external
@nonreentrant
def transferFrom(owner: address, to: address, token_id: uint256):
    """
    @notice Transfer ve-locked NFT which the CliffEscrow has access to anywhere - only after cliff is finished
    """
    self._access()
    self._cliff()
    extcall VE.transferFrom(owner, to, token_id)


@external
@nonreentrant
def vote_for_gauge_weights(_gauge_addrs: DynArray[address, 50], _user_weights: DynArray[uint256, 50]):
    """
    @notice Vote for gauge weights from inside the CliffEscrow with a ve-lock we created
    @param _gauge_addrs Gauges to vote for
    @param _user_weights Voting weights of the gauges
    """
    self._access()
    extcall GC.vote_for_gauge_weights(_gauge_addrs, _user_weights)


@external
@nonreentrant
def aragon_vote(dao: AragonDAO, proposal_id: uint256, vote_option: uint8, early_execution: bool):
    """
    @notice Perform an Aragon vote using ve-lock we have inside CliffEscrow
    @param dao Aragon DAO voting plugin address
    @param proposal_id Proposal to vote for
    @param vote_option Option to choose when voting
    @param early_execution Early execution parameter
    """
    self._access()
    extcall dao.vote(proposal_id, vote_option, early_execution)


@external
@nonreentrant
def infinite_lock_toggle():
    """
    @notice Make ve-lock automatically relocking or remove this setting
    """
    self._access()
    extcall VE.infinite_lock_toggle()


@external
@nonreentrant
def transfer(to: address, amount: uint256):
    """
    @notice Transfer the token (not ve-lock!) anywhere. Requires cliff to be finished.
            Recipient of CliffEscrow can transfer anywhere, but everyone else only to recipient.
    """
    assert self.recipient in [msg.sender, to], "Not authorized"
    # If msg.sender is recipient - they can transfer anywhere
    # If msg.sender is NOT recipient - they can transfer only to recipient
    self._cliff()
    extcall YB.transfer(to, amount)


@external
@nonreentrant
def approve(_for: address, amount: uint256):
    """
    @notice Approve the cliff-affected tokens for transfering out. Only after cliff is finished.
    @param _for Address which can take our tokens
    @param amount Amount approved
    """
    self._access()
    self._cliff()
    extcall YB.approve(_for, amount)


@external
@nonreentrant
def recover_token(token: IERC20, to: address, amount: uint256):
    """
    @notice Recover (send) any token not affected by cliff
    @param token Token to recover
    @param to Address to send to
    @param amount Amount of token to send
    """
    self._access()
    assert token != YB, "Cannot recover YB"
    assert extcall token.transfer(to, amount, default_return_value=True)
    log TokenRecovered(token=token.address, to=to, amount=amount)

Settings
{
  "outputSelection": {
    "contracts/dao/CliffEscrow.vy": [
      "evm.bytecode",
      "evm.deployedBytecode",
      "abi"
    ]
  },
  "search_paths": [
    "."
  ]
}

Contract ABI

API
[{"anonymous":false,"inputs":[{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"TokenRecovered","type":"event"},{"inputs":[{"name":"recipient","type":"address"},{"name":"unlock_time","type":"uint256"}],"name":"initialize","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_value","type":"uint256"},{"name":"_unlock_time","type":"uint256"}],"name":"create_lock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_value","type":"uint256"}],"name":"increase_amount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_unlock_time","type":"uint256"}],"name":"increase_unlock_time","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"owner","type":"address"},{"name":"to","type":"address"},{"name":"token_id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_gauge_addrs","type":"address[]"},{"name":"_user_weights","type":"uint256[]"}],"name":"vote_for_gauge_weights","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"dao","type":"address"},{"name":"proposal_id","type":"uint256"},{"name":"vote_option","type":"uint8"},{"name":"early_execution","type":"bool"}],"name":"aragon_vote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"infinite_lock_toggle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"to","type":"address"},{"name":"amount","type":"uint256"}],"name":"transfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_for","type":"address"},{"name":"amount","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"token","type":"address"},{"name":"to","type":"address"},{"name":"amount","type":"uint256"}],"name":"recover_token","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"GC","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"YB","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VE","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unlock_time","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"recipient","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"token","type":"address"},{"name":"ve","type":"address"},{"name":"gc","type":"address"}],"outputs":[],"stateMutability":"nonpayable","type":"constructor"}]

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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