Latest 25 from a total of 35 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Claim | 427072527 | 35 hrs ago | IN | 0 ETH | 0.00000159 | ||||
| Claim | 425705258 | 5 days ago | IN | 0 ETH | 0.00000158 | ||||
| Claim | 425166527 | 6 days ago | IN | 0 ETH | 0.00000159 | ||||
| Claim | 423020029 | 13 days ago | IN | 0 ETH | 0.00000158 | ||||
| Claim | 420818410 | 19 days ago | IN | 0 ETH | 0.00000158 | ||||
| Claim | 418179245 | 27 days ago | IN | 0 ETH | 0.00000079 | ||||
| Claim | 416501870 | 32 days ago | IN | 0 ETH | 0.00000079 | ||||
| Claim | 414046978 | 39 days ago | IN | 0 ETH | 0.00000662 | ||||
| Claim | 413233180 | 41 days ago | IN | 0 ETH | 0.00000079 | ||||
| Claim | 410902033 | 48 days ago | IN | 0 ETH | 0.00000079 | ||||
| Claim | 409940955 | 51 days ago | IN | 0 ETH | 0.00000211 | ||||
| Claim | 409097883 | 53 days ago | IN | 0 ETH | 0.00000079 | ||||
| Claim | 408414444 | 55 days ago | IN | 0 ETH | 0.00000079 | ||||
| Claim | 407482817 | 58 days ago | IN | 0 ETH | 0.00001621 | ||||
| Claim | 406670213 | 60 days ago | IN | 0 ETH | 0.00000079 | ||||
| Claim | 405986166 | 62 days ago | IN | 0 ETH | 0.0000009 | ||||
| Claim | 404983477 | 65 days ago | IN | 0 ETH | 0.00000062 | ||||
| Claim | 404611333 | 66 days ago | IN | 0 ETH | 0.00000079 | ||||
| Claim | 402301654 | 73 days ago | IN | 0 ETH | 0.00001426 | ||||
| Claim | 399049496 | 82 days ago | IN | 0 ETH | 0.00000079 | ||||
| Claim | 396358740 | 90 days ago | IN | 0 ETH | 0.00000081 | ||||
| Claim | 395350107 | 93 days ago | IN | 0 ETH | 0.00000116 | ||||
| Claim | 389800885 | 109 days ago | IN | 0 ETH | 0.00000205 | ||||
| Claim | 389094314 | 111 days ago | IN | 0 ETH | 0.00000144 | ||||
| Claim | 387039450 | 117 days ago | IN | 0 ETH | 0.00000381 |
Latest 1 internal transaction
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 377750129 | 144 days ago | Contract Creation | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Minimal Proxy Contract for 0x4ace3edd57eff1176a862e7b72db090ecf2b84bd
Contract Name:
Simple Vesting Escrow
Compiler Version
vyper:0.3.10
Contract Source Code (Vyper language format)
# @version 0.3.10
"""
@title Simple Vesting Escrow
@author Curve Finance, Yearn Finance
@license MIT
@notice Vests ERC20 tokens for a single address
@dev Intended to be deployed many times via `VotingEscrowFactory`
"""
from vyper.interfaces import ERC20
event Claim:
recipient: indexed(address)
claimed: uint256
event Revoked:
recipient: address
owner: address
rugged: uint256
ts: uint256
event Disowned:
owner: address
event SetOpenClaim:
state: bool
recipient: public(address)
token: public(ERC20)
start_time: public(uint256)
end_time: public(uint256)
cliff_length: public(uint256)
total_locked: public(uint256)
total_claimed: public(uint256)
disabled_at: public(uint256)
open_claim: public(bool)
initialized: public(bool)
owner: public(address)
@external
def __init__():
# ensure that the original contract cannot be initialized
self.initialized = True
@external
def initialize(
owner: address,
token: ERC20,
recipient: address,
amount: uint256,
start_time: uint256,
end_time: uint256,
cliff_length: uint256,
open_claim: bool,
) -> bool:
"""
@notice Initialize the contract
@dev This function is seperate from `__init__` because of the factory pattern
used in `VestingEscrowFactory.deploy_vesting_contract`. It may be called
once per deployment
@param owner Owner address
@param token Address of the ERC20 token being distributed
@param recipient Address to vest tokens for
@param amount Amount of tokens being vested for `recipient`
@param start_time Epoch time at which token distribution starts
@param end_time Time until everything should be vested
@param cliff_length Duration (in seconds) after which the first portion vests
@param open_claim Switch if anyone can claim for `recipient`
"""
assert not self.initialized # dev: can only initialize once
self.initialized = True
self.token = token
self.owner = owner
self.start_time = start_time
self.end_time = end_time
self.cliff_length = cliff_length
self.recipient = recipient
self.disabled_at = end_time # Set to maximum time
self.total_locked = amount
self.open_claim = open_claim
return True
@internal
@view
def _total_vested_at(time: uint256 = block.timestamp) -> uint256:
start: uint256 = self.start_time
end: uint256 = self.end_time
locked: uint256 = self.total_locked
if time < start + self.cliff_length:
return 0
return min(locked * (time - start) / (end - start), locked)
@internal
@view
def _unclaimed(time: uint256 = block.timestamp) -> uint256:
return self._total_vested_at(time) - self.total_claimed
@external
@view
def unclaimed() -> uint256:
"""
@notice Get the number of unclaimed, vested tokens for recipient
@dev If `revoke` is activated, limit by the activation timestamp
"""
return self._unclaimed(min(block.timestamp, self.disabled_at))
@internal
@view
def _locked(time: uint256 = block.timestamp) -> uint256:
return self._total_vested_at(self.disabled_at) - self._total_vested_at(time)
@external
@view
def locked() -> uint256:
"""
@notice Get the number of locked tokens for recipient
@dev If `revoke` is activated, limit by the activation timestamp
"""
return self._locked(min(block.timestamp, self.disabled_at))
@external
def claim(beneficiary: address = msg.sender, amount: uint256 = max_value(uint256)) -> uint256:
"""
@notice Claim tokens which have vested
@param beneficiary Address to transfer claimed tokens to
@param amount Amount of tokens to claim
"""
recipient: address = self.recipient
assert msg.sender == recipient or self.open_claim and recipient == beneficiary # dev: not authorized
claim_period_end: uint256 = min(block.timestamp, self.disabled_at)
claimable: uint256 = min(self._unclaimed(claim_period_end), amount)
self.total_claimed += claimable
assert self.token.transfer(beneficiary, claimable, default_return_value=True)
log Claim(beneficiary, claimable)
return claimable
@external
def revoke(ts: uint256 = block.timestamp, beneficiary: address = msg.sender):
"""
@notice Disable further flow of tokens and clawback the unvested part to `beneficiary`
Revoking more than once is futile
@dev Owner is set to zero address
@param ts Timestamp of the clawback
@param beneficiary Recipient of the unvested part
"""
owner: address = self.owner
assert msg.sender == owner # dev: not owner
assert ts >= block.timestamp and ts < self.end_time # dev: no back to the future
ruggable: uint256 = self._locked(ts)
self.disabled_at = ts
self.owner = empty(address)
assert self.token.transfer(beneficiary, ruggable, default_return_value=True)
log Disowned(owner)
log Revoked(self.recipient, owner, ruggable, ts)
@external
def disown():
"""
@notice Renounce owner control of the escrow
"""
owner: address = self.owner
assert msg.sender == owner # dev: not owner
self.owner = empty(address)
log Disowned(owner)
@external
def set_open_claim(open_claim: bool):
"""
@notice Disallow or let anyone claim tokens for `recipient`
"""
assert msg.sender == self.recipient # dev: not recipient
self.open_claim = open_claim
log SetOpenClaim(open_claim)
@external
def collect_dust(token: ERC20, beneficiary: address = msg.sender):
recipient: address = self.recipient
assert msg.sender == recipient or self.open_claim and recipient == beneficiary # dev: not authorized
amount: uint256 = token.balanceOf(self)
if token == self.token:
amount = amount + self.total_claimed - self._total_vested_at(self.disabled_at)
assert token.transfer(beneficiary, amount, default_return_value=True)
assert self.token.balanceOf(self) >= (self._total_vested_at(self.disabled_at) - self.total_claimed)Contract ABI
API[{"name":"Claim","inputs":[{"name":"recipient","type":"address","indexed":true},{"name":"claimed","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"Revoked","inputs":[{"name":"recipient","type":"address","indexed":false},{"name":"owner","type":"address","indexed":false},{"name":"rugged","type":"uint256","indexed":false},{"name":"ts","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"Disowned","inputs":[{"name":"owner","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"SetOpenClaim","inputs":[{"name":"state","type":"bool","indexed":false}],"anonymous":false,"type":"event"},{"stateMutability":"nonpayable","type":"constructor","inputs":[],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"initialize","inputs":[{"name":"owner","type":"address"},{"name":"token","type":"address"},{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"},{"name":"start_time","type":"uint256"},{"name":"end_time","type":"uint256"},{"name":"cliff_length","type":"uint256"},{"name":"open_claim","type":"bool"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"view","type":"function","name":"unclaimed","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"locked","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"claim","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"claim","inputs":[{"name":"beneficiary","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"claim","inputs":[{"name":"beneficiary","type":"address"},{"name":"amount","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"revoke","inputs":[],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"revoke","inputs":[{"name":"ts","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"revoke","inputs":[{"name":"ts","type":"uint256"},{"name":"beneficiary","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"disown","inputs":[],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"set_open_claim","inputs":[{"name":"open_claim","type":"bool"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"collect_dust","inputs":[{"name":"token","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"collect_dust","inputs":[{"name":"token","type":"address"},{"name":"beneficiary","type":"address"}],"outputs":[]},{"stateMutability":"view","type":"function","name":"recipient","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"token","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"start_time","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"end_time","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"cliff_length","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"total_locked","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"total_claimed","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"disabled_at","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"open_claim","inputs":[],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"view","type":"function","name":"initialized","inputs":[],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"view","type":"function","name":"owner","inputs":[],"outputs":[{"name":"","type":"address"}]}]Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$878.53
Net Worth in ETH
0.373992
Token Allocations
GRAIL
100.00%
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ARB | 100.00% | $102.45 | 8.5752 | $878.53 |
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.