Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

VestingWalletUpgradeable

Inherits: Initializable, ContextUpgradeable, OwnableUpgradeable

A vesting wallet is an ownable contract that can receive native currency and ERC-20 tokens, and release these assets to the wallet owner, also referred to as "beneficiary", according to a vesting schedule. Any assets transferred to this contract will follow the vesting schedule as if they were locked from the beginning. Consequently, if the vesting has already started, any amount of tokens sent to this contract will (at least partly) be immediately releasable. By setting the duration to 0, one can configure this contract to behave like an asset timelock that holds tokens for a beneficiary until a specified time. NOTE: Since the wallet is {Ownable}, and ownership can be transferred, it is possible to sell unvested tokens. Preventing this in a smart contract is difficult, considering that: 1) a beneficiary address could be a counterfactually deployed contract, 2) there is likely to be a migration path for EOAs to become contracts in the near future. NOTE: When using this contract with any token whose balance is adjusted automatically (i.e. a rebase token), make sure to account the supply/balance adjustment in the vesting schedule to ensure the vested amount is as intended. NOTE: Chains with support for native ERC20s may allow the vesting wallet to withdraw the underlying asset as both an ERC20 and as native currency. For example, if chain C supports token A and the wallet gets deposited 100 A, then at 50% of the vesting period, the beneficiary can withdraw 50 A as ERC20 and 25 A as native currency (totaling 75 A). Consider disabling one of the withdrawal methods.

State Variables

VestingWalletStorageLocation

bytes32 private constant VestingWalletStorageLocation =
    0xa1eac494560f7591e4da38ed031587f09556afdfc4399dd2e205b935fdfa3900;

Functions

_getVestingWalletStorage

function _getVestingWalletStorage() private pure returns (VestingWalletStorage storage $);

initialize

function initialize(address beneficiary, uint64 startTimestamp, uint64 durationSeconds) public virtual initializer;

__VestingWallet_init

Sets the beneficiary (owner), the start timestamp and the vesting duration (in seconds) of the vesting wallet.

function __VestingWallet_init(address beneficiary, uint64 startTimestamp, uint64 durationSeconds)
    internal
    onlyInitializing;

__VestingWallet_init_unchained

function __VestingWallet_init_unchained(address, uint64 startTimestamp, uint64 durationSeconds)
    internal
    onlyInitializing;

receive

The contract should be able to receive Eth.

receive() external payable virtual;

start

Getter for the start timestamp.

function start() public view virtual returns (uint256);

duration

Getter for the vesting duration.

function duration() public view virtual returns (uint256);

end

Getter for the end timestamp.

function end() public view virtual returns (uint256);

released

Amount of eth already released

function released() public view virtual returns (uint256);

released

Amount of token already released

function released(address token) public view virtual returns (uint256);

releasable

Getter for the amount of releasable eth.

function releasable() public view virtual returns (uint256);

releasable

Getter for the amount of releasable token tokens. token should be the address of an {IERC20} contract.

function releasable(address token) public view virtual returns (uint256);

release

Release the native token (ether) that have already vested. Emits a EtherReleased event.

function release() public virtual;

release

Release the tokens that have already vested. Emits a ERC20Released event.

function release(address token) public virtual;

vestedAmount

Calculates the amount of ether that has already vested. Default implementation is a linear vesting curve.

function vestedAmount(uint64 timestamp) public view virtual returns (uint256);

vestedAmount

Calculates the amount of tokens that has already vested. Default implementation is a linear vesting curve.

function vestedAmount(address token, uint64 timestamp) public view virtual returns (uint256);

_vestingSchedule

Virtual implementation of the vesting formula. This returns the amount vested, as a function of time, for an asset given its total historical allocation.

function _vestingSchedule(uint256 totalAllocation, uint64 timestamp) internal view virtual returns (uint256);

Events

EtherReleased

event EtherReleased(uint256 amount);

ERC20Released

event ERC20Released(address indexed token, uint256 amount);

Structs

VestingWalletStorage

Note: storage-location: erc7201:openzeppelin.storage.VestingWallet

struct VestingWalletStorage {
    uint256 _released;
    mapping(address token => uint256) _erc20Released;
    uint64 _start;
    uint64 _duration;
}