Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 85 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Claim | 20423616 | 97 days ago | IN | 0 ETH | 0.00027701 | ||||
Claim | 20395545 | 100 days ago | IN | 0 ETH | 0.0000895 | ||||
Claim | 20300197 | 114 days ago | IN | 0 ETH | 0.00014895 | ||||
Claim | 20228918 | 124 days ago | IN | 0 ETH | 0.00055196 | ||||
Claim | 20136820 | 137 days ago | IN | 0 ETH | 0.00021431 | ||||
Claim | 20108282 | 141 days ago | IN | 0 ETH | 0.00029195 | ||||
Claim | 20084414 | 144 days ago | IN | 0 ETH | 0.00091788 | ||||
Claim | 20036548 | 151 days ago | IN | 0 ETH | 0.00076446 | ||||
Claim | 19984441 | 158 days ago | IN | 0 ETH | 0.00119736 | ||||
Claim | 19956628 | 162 days ago | IN | 0 ETH | 0.00042708 | ||||
Claim | 19924667 | 166 days ago | IN | 0 ETH | 0.00050248 | ||||
Claim | 19914165 | 168 days ago | IN | 0 ETH | 0.0019464 | ||||
Claim | 19891612 | 171 days ago | IN | 0 ETH | 0.00032871 | ||||
Claim | 19821596 | 181 days ago | IN | 0 ETH | 0.00033014 | ||||
Claim | 19808863 | 182 days ago | IN | 0 ETH | 0.00032835 | ||||
Claim | 19792199 | 185 days ago | IN | 0 ETH | 0.0005009 | ||||
Claim | 19782147 | 186 days ago | IN | 0 ETH | 0.00049527 | ||||
Claim | 19754915 | 190 days ago | IN | 0 ETH | 0.00071505 | ||||
Claim | 19743305 | 192 days ago | IN | 0 ETH | 0.00043704 | ||||
Claim | 19728726 | 194 days ago | IN | 0 ETH | 0.0006539 | ||||
Claim | 19701021 | 198 days ago | IN | 0 ETH | 0.00049227 | ||||
Claim | 19687727 | 199 days ago | IN | 0 ETH | 0.00063545 | ||||
Claim | 19649590 | 205 days ago | IN | 0 ETH | 0.00830194 | ||||
Claim | 19588989 | 213 days ago | IN | 0 ETH | 0.0011735 | ||||
Claim | 19493187 | 227 days ago | IN | 0 ETH | 0.00150873 |
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
17791361 | 465 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Minimal Proxy Contract for 0x80429330c476857bafddf61772bfe1263d765a1f
Contract Name:
Vesting
Compiler Version
v0.8.15+commit.e14f2714
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BSD-3-Clause pragma solidity ^0.8.13; import {IERC20} from "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import {IVesting} from "src/interfaces/IVesting.sol"; import {IVestingFactory} from "src/interfaces/IVestingFactory.sol"; /*////////////////////////////////////////////////////////////// CUSTOM ERROR //////////////////////////////////////////////////////////////*/ error NotInitialised(); error Initialised(); error NoAccess(); error ZeroAddress(); error NoVestingData(); error StartLessThanNow(); error ZeroAmount(); error ZeroClaimAmount(); error AlreadyClaimed(); error AlreadyCancelled(); error Uncancellable(); error SameRecipient(); /*////////////////////////////////////////////////////////////// CONTRACT //////////////////////////////////////////////////////////////*/ /// @title Vesting Contract contract Vesting is IVesting { // The recipient of the tokens address public recipient; uint40 public start; uint40 public duration; uint256 public amount; // Total amount of tokens which are claimed uint256 public totalClaimedAmount; // Flag for whether the vesting is cancellable or not bool public isCancellable; // Flag for whether the vesting is cancelled or not bool public cancelled; // Flag to check if its initialised bool private initialised; IVestingFactory public factory; /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ function initialise(address _recipient, uint40 _start, uint40 _duration, uint256 _amount, bool _isCancellable) external override { if (initialised) revert Initialised(); initialised = true; recipient = _recipient; start = _start; duration = _duration; amount = _amount; isCancellable = _isCancellable; factory = IVestingFactory(msg.sender); } /*////////////////////////////////////////////////////////////// MODIFIERS //////////////////////////////////////////////////////////////*/ modifier onlyTreasury() { if (msg.sender != factory.treasury()) revert NoAccess(); _; } modifier onlyOwner() { bool isOwner; if (isCancellable == false) { // If the vest is uncancellable, only the recipient can call the function isOwner = (msg.sender == recipient); } else { // If the vest is cancellable, only the treasury or the recipient can call the function isOwner = (msg.sender == recipient) || (msg.sender == factory.treasury()); } if (!isOwner) revert NoAccess(); _; } modifier onlyInit() { if (!initialised) revert NotInitialised(); _; } /*////////////////////////////////////////////////////////////// VIEW FUNCTIONS //////////////////////////////////////////////////////////////*/ /// @notice Calculates the amount of tokens which have been accrued to date. /// @notice This does not take into account the amount which has been claimed already. /// @return uint256 The amount of tokens which have been accrued to date. function getAccruedTokens() public view returns (uint256) { if (block.timestamp >= start + duration) { return amount; } else if (block.timestamp < start) { // Allows us to set up vests in advance return 0; } else { return (block.timestamp - start) * (amount / duration); } } /// @notice Calculates the amount of tokens which can be claimed. /// @return uint256 The amount of tokens which can be claimed. function getClaimableTokens() public view returns (uint256) { if (cancelled) { return 0; } uint256 accruedTokens = getAccruedTokens(); // Calculate the amount of tokens which can be claimed uint256 tokensToClaim = accruedTokens - totalClaimedAmount; return tokensToClaim; } /// @notice Gets the vesting details of the contract. function getVestingDetails() public view returns (uint40, uint40, uint256, uint256, bool) { return (start, duration, amount, totalClaimedAmount, isCancellable); } function getTokens() public view returns (uint256) { // Assumes that the token has 18 decimals return amount / (10 ** 18); } /*////////////////////////////////////////////////////////////// EXTERNAL FUNCTIONS //////////////////////////////////////////////////////////////*/ /// @notice Changes the recipient of vested tokens. /// @notice The old recipient will not be able to claim the tokens, the new recipient will be able to claim all unclaimed tokens accrued to date. /// @dev Can be called by the treasury or the recipient depending on whether the vest is cancellable or not. /// @param _newRecipient Address of the new recipient recieving the vested tokens. function changeRecipient(address _newRecipient) external onlyOwner onlyInit { if (_newRecipient == address(0)) revert ZeroAddress(); if (_newRecipient == recipient) revert SameRecipient(); if (start == 0) revert NoVestingData(); if (cancelled) revert AlreadyCancelled(); factory.changeRecipient(recipient, _newRecipient); recipient = _newRecipient; } /// @notice Cancels the vest and transfers the accrued amount to the recipient. /// @dev Can only be called by the treasury. function cancelVest() external onlyTreasury onlyInit { if (start < 1) revert NoVestingData(); if (isCancellable == false) revert Uncancellable(); if (cancelled) revert AlreadyCancelled(); uint256 claimAmount = getClaimableTokens(); if (claimAmount > 0) { totalClaimedAmount += claimAmount; factory.token().transfer(recipient, claimAmount); } cancelled = true; // Transfer the remainder of the tokens to the treasury factory.token().transfer(factory.treasury(), amount - totalClaimedAmount); } /// @notice A function allowing the recipient to claim the vested tokens. /// @notice The function returns unclaimed tokens to the treasury. /// @dev This function can be called by anyone. function claim() public override onlyInit { if (totalClaimedAmount >= amount) revert AlreadyClaimed(); if (cancelled) revert AlreadyCancelled(); uint256 claimAmount = getClaimableTokens(); if (claimAmount < 1) revert ZeroClaimAmount(); totalClaimedAmount += claimAmount; factory.token().transfer(recipient, claimAmount); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: BSD-3-Clause pragma solidity ^0.8.0; interface IVesting { function cancelled() external returns (bool); function totalClaimedAmount() external returns (uint256); function amount() external returns (uint256); function initialise(address _recipient, uint40 _start, uint40 _duration, uint256 _amount, bool _isCancellable) external; function claim() external; }
// SPDX-License-Identifier: BSD-3-Clause pragma solidity ^0.8.0; import {IERC20} from "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; interface IVestingFactory { function treasury() external returns (address); function token() external returns (IERC20); function changeRecipient(address _oldRecipient, address _newRecipient) external; }
{ "remappings": [ "ds-test/=lib/forge-std/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
[{"inputs":[],"name":"AlreadyCancelled","type":"error"},{"inputs":[],"name":"AlreadyClaimed","type":"error"},{"inputs":[],"name":"Initialised","type":"error"},{"inputs":[],"name":"NoAccess","type":"error"},{"inputs":[],"name":"NoVestingData","type":"error"},{"inputs":[],"name":"NotInitialised","type":"error"},{"inputs":[],"name":"SameRecipient","type":"error"},{"inputs":[],"name":"Uncancellable","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroClaimAmount","type":"error"},{"inputs":[],"name":"amount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelVest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cancelled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newRecipient","type":"address"}],"name":"changeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"duration","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"contract IVestingFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAccruedTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getClaimableTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVestingDetails","outputs":[{"internalType":"uint40","name":"","type":"uint40"},{"internalType":"uint40","name":"","type":"uint40"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint40","name":"_start","type":"uint40"},{"internalType":"uint40","name":"_duration","type":"uint40"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"_isCancellable","type":"bool"}],"name":"initialise","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isCancellable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"recipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"start","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalClaimedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.