LinearVesting
Inherits: DerivativeModule, ILinearVesting, LinearVestingCard
A derivative module that allows for the creation of linearly vesting tokens
This module allows for the creation of linearly vesting tokens, where the vesting period is defined by a start and expiry timestamp. The tokens can be wrapped and unwrapped, and the underlying tokens can be redeemed once vested. The start timestamp enables vesting tokens to have a cliff, after which vesting commences.
State Variables
_VESTING_PARAMS_LEN
uint256 internal immutable _VESTING_PARAMS_LEN = 64;
_IMPLEMENTATION
Stores the clonable implementation of the wrapped derivative token
address internal immutable _IMPLEMENTATION;
userClaimed
Stores the amount that a user has claimed
mapping(address owner_ => mapping(uint256 tokenId_ => uint256 claimed_)) public userClaimed;
Functions
constructor
constructor(address parent_) Module(parent_) LinearVestingCard();
TYPE
2 byte identifier for the module type
This enables the parent contract to check that the module Keycode specified
function TYPE() public pure override returns (Type);
VEECODE
7 byte, versioned identifier for the module. 2 characters from 0-9 that signify the version and 3-5 characters from A-Z.
function VEECODE() public pure override returns (Veecode);
onlyValidTokenId
modifier onlyValidTokenId(uint256 tokenId_);
onlyDeployedWrapped
modifier onlyDeployedWrapped(uint256 tokenId_);
transfer
Transfers are disabled
Vesting tokens are soulbound/not transferable
function transfer(address, uint256, uint256) public virtual override returns (bool);
transferFrom
Transfers are disabled
Vesting tokens are soulbound/not transferable
function transferFrom(address, address, uint256, uint256) public virtual override returns (bool);
approve
Transfers are disabled
Vesting tokens are soulbound/not transferable
function approve(address, uint256, uint256) public virtual override returns (bool);
deploy
Deploy a new derivative token. Optionally, deploys an ERC20 wrapper for composability.
This function performs the following:
- Validates the parameters
- Deploys the derivative token if it does not already exist
This function reverts if:
- The parameters are in an invalid format
- The parameters fail validation
function deploy(
address underlyingToken_,
bytes memory params_,
bool wrapped_
) external virtual override returns (uint256 tokenId_, address wrappedAddress_);
Parameters
Name | Type | Description |
---|---|---|
underlyingToken_ | address | The address of the underlying token |
params_ | bytes | ABI-encoded parameters for the derivative to be created |
wrapped_ | bool | Whether (true) or not (false) the derivative should be wrapped in an ERC20 token for composability |
Returns
Name | Type | Description |
---|---|---|
tokenId_ | uint256 | The ID of the newly created derivative token |
wrappedAddress_ | address | The address of the ERC20 wrapped derivative token, if wrapped_ is true, otherwise, it's the zero address. |
_mintDeployed
Mints the derivative token to the recipient, assuming that the derivative token has already been deployed
function _mintDeployed(
address to_,
uint256 tokenId_,
uint256 amount_,
Token storage token_,
bool wrapped_
) internal;
Parameters
Name | Type | Description |
---|---|---|
to_ | address | The address of the recipient of the derivative token |
tokenId_ | uint256 | The ID of the derivative token |
amount_ | uint256 | The amount of the derivative token to mint |
token_ | Token | The metadata for the derivative token |
wrapped_ | bool | Whether or not to wrap the derivative token |
mint
Mint new derivative tokens.
This function performs the following:
- Validates the parameters
- Deploys the derivative token if it does not already exist
- Mints the derivative token to the recipient
This function reverts if:
- The parameters are in an invalid format
- The parameters fail validation
amount_
is 0
A derivative token can be minted after vesting expiry, which prevents mitigates problems with auctions that settle late.
function mint(
address to_,
address underlyingToken_,
bytes memory params_,
uint256 amount_,
bool wrapped_
)
external
virtual
override
returns (uint256 tokenId_, address wrappedAddress_, uint256 amountCreated_);
Parameters
Name | Type | Description |
---|---|---|
to_ | address | The address to mint the derivative tokens to |
underlyingToken_ | address | The address of the underlying token |
params_ | bytes | ABI-encoded parameters for the derivative to be created |
amount_ | uint256 | The amount of derivative tokens to create |
wrapped_ | bool | Whether (true) or not (false) the derivative should be wrapped in an ERC20 token for composability |
Returns
Name | Type | Description |
---|---|---|
tokenId_ | uint256 | The ID of the newly created derivative token |
wrappedAddress_ | address | The address of the ERC20 wrapped derivative token, if wrapped_ is true, otherwise, it's the zero address. |
amountCreated_ | uint256 | The amount of derivative tokens created |
mint
Mint new derivative tokens.
This function performs the following:
- Mints the derivative token to the recipient
This function reverts if:
tokenId_
does not exist- The amount to mint is 0
A derivative token can be minted after vesting expiry, which prevents mitigates problems with auctions that settle late.
function mint(
address to_,
uint256 tokenId_,
uint256 amount_,
bool wrapped_
) external virtual override onlyValidTokenId(tokenId_) returns (uint256, address, uint256);
Parameters
Name | Type | Description |
---|---|---|
to_ | address | The address to mint the derivative tokens to |
tokenId_ | uint256 | |
amount_ | uint256 | The amount of derivative tokens to create |
wrapped_ | bool | Whether (true) or not (false) the derivative should be wrapped in an ERC20 token for composability |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | tokenId_ The ID of the newly created derivative token |
<none> | address | wrappedAddress* The address of the ERC20 wrapped derivative token, if wrapped* is true, otherwise, it's the zero address. |
<none> | uint256 | amountCreated_ The amount of derivative tokens created |
_redeem
Redeems the derivative token for the underlying base token
This function assumes that validation has already been performed
function _redeem(uint256 tokenId_, address user_, uint256 amount_) internal;
Parameters
Name | Type | Description |
---|---|---|
tokenId_ | uint256 | The ID of the derivative token |
user_ | address | The address of the owner of the derivative token |
amount_ | uint256 | The amount of the derivative token to redeem |
redeemMax
Redeem all available derivative tokens for underlying collateral
function redeemMax(uint256 tokenId_) external virtual override onlyValidTokenId(tokenId_);
Parameters
Name | Type | Description |
---|---|---|
tokenId_ | uint256 | The ID of the derivative token to redeem |
redeem
Redeem derivative tokens for underlying collateral
This function reverts if:
amount_
is 0- The redeemable amount is less than
amount_
- The derivative token with
tokenId_
has not been deployed
function redeem(
uint256 tokenId_,
uint256 amount_
) external virtual override onlyValidTokenId(tokenId_);
Parameters
Name | Type | Description |
---|---|---|
tokenId_ | uint256 | The ID of the derivative token to redeem |
amount_ | uint256 | The amount of derivative tokens to redeem |
redeemable
Determines the amount of redeemable tokens for a given derivative token
The redeemable amount is computed as:
- The amount of tokens that have vested
- x: number of vestable tokens
- t: current timestamp
- s: start timestamp
- T: expiry timestamp
- _Vested = x _ (t - s) / (T - s)*
- Minus the amount of tokens that have already been redeemed
function redeemable(
address owner_,
uint256 tokenId_
) public view virtual override onlyValidTokenId(tokenId_) returns (uint256);
Parameters
Name | Type | Description |
---|---|---|
owner_ | address | The owner of the derivative token |
tokenId_ | uint256 | The ID of the derivative token |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | amount The amount of redeemable tokens |
exercise
Exercise a conversion of the derivative token per the specific implementation logic
Not implemented
function exercise(uint256, uint256) external virtual override;
Parameters
Name | Type | Description |
---|---|---|
<none> | uint256 | |
<none> | uint256 |
exerciseCost
Determines the cost to exercise a derivative token in the quoted token
Not implemented
function exerciseCost(uint256, uint256) external view virtual override returns (uint256);
Parameters
Name | Type | Description |
---|---|---|
<none> | uint256 | |
<none> | uint256 |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | cost The cost to exercise the derivative token |
reclaim
Reclaim posted collateral for a derivative token which can no longer be exercised
Not implemented
function reclaim(uint256) external virtual override;
Parameters
Name | Type | Description |
---|---|---|
<none> | uint256 |
transform
Transforms an existing derivative issued by this contract into something else. Derivative is burned and collateral sent to the auction house.
Not implemented
function transform(uint256, address, uint256) external virtual override;
Parameters
Name | Type | Description |
---|---|---|
<none> | uint256 | |
<none> | address | |
<none> | uint256 |
wrap
Wrap an existing derivative into an ERC20 token for composability Deploys the ERC20 wrapper if it does not already exist
This function will revert if:
- The derivative token with
tokenId_
has not been deployed amount_
is 0
function wrap(uint256 tokenId_, uint256 amount_) external override onlyValidTokenId(tokenId_);
Parameters
Name | Type | Description |
---|---|---|
tokenId_ | uint256 | The ID of the derivative token to wrap |
amount_ | uint256 | The amount of derivative tokens to wrap |
unwrap
Unwrap an ERC20 derivative token into the underlying ERC6909 derivative
This function will revert if:
- The derivative token with
tokenId_
has not been deployed - A wrapped derivative for
tokenId_
has not been deployed amount_
is 0
function unwrap(
uint256 tokenId_,
uint256 amount_
) external override onlyValidTokenId(tokenId_) onlyDeployedWrapped(tokenId_);
Parameters
Name | Type | Description |
---|---|---|
tokenId_ | uint256 | The ID of the derivative token to unwrap |
amount_ | uint256 | The amount of derivative tokens to unwrap |
_validate
Validates the parameters for a derivative token
This function performs the following checks:
- The start and expiry times are not 0
- The start time is before the expiry time
- The underlying token is not the zero address
The start and expiry times do not have to be before the current block timestamp, as it is possible to deploy and mint derivative tokens after the vesting expiry. Otherwise, it would be possible to brick funds by delaying the auction settlement.
function _validate(
address underlyingToken_,
VestingParams memory data_
) internal pure returns (bool);
Parameters
Name | Type | Description |
---|---|---|
underlyingToken_ | address | The address of the underlying token |
data_ | VestingParams | The parameters for the derivative token |
Returns
Name | Type | Description |
---|---|---|
<none> | bool | bool True if the parameters are valid, otherwise false |
validate
Validate derivative params for the specific implementation
The parameters should be the same as what is passed into deploy()
or mint()
function validate(
address underlyingToken_,
bytes memory params_
) public pure override returns (bool);
Parameters
Name | Type | Description |
---|---|---|
underlyingToken_ | address | The address of the underlying token |
params_ | bytes | The abi-encoded VestingParams for the derivative token |
Returns
Name | Type | Description |
---|---|---|
<none> | bool | isValid Whether or not the params are valid |
_getTokenMetadata
function _getTokenMetadata(uint256 tokenId_) internal view returns (ERC20, VestingParams memory);
getTokenVestingParams
Get the vesting parameters for a derivative token
function getTokenVestingParams(
uint256 tokenId_
) external view onlyValidTokenId(tokenId_) returns (VestingParams memory);
Parameters
Name | Type | Description |
---|---|---|
tokenId_ | uint256 |
Returns
Name | Type | Description |
---|---|---|
<none> | VestingParams | vestingParams The vesting parameters |
computeId
Compute a unique token ID, given the parameters for the derivative
function computeId(
address underlyingToken_,
bytes memory params_
) external pure virtual override returns (uint256);
Parameters
Name | Type | Description |
---|---|---|
underlyingToken_ | address | The address of the underlying token |
params_ | bytes | The abi-encoded VestingParams for the derivative token |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | tokenId The unique token ID |
_decodeVestingParams
Decodes the ABI-encoded VestingParams
for a derivative token
This function will revert if the parameters are not the correct length
function _decodeVestingParams(bytes memory params_) internal pure returns (VestingParams memory);
_computeId
Computes the ID of a derivative token
The ID is computed as the hash of the parameters and hashed again with the module identifier.
function _computeId(ERC20 base_, uint48 start_, uint48 expiry_) internal pure returns (uint256);
Parameters
Name | Type | Description |
---|---|---|
base_ | ERC20 | The address of the underlying token |
start_ | uint48 | The timestamp at which the vesting starts |
expiry_ | uint48 | The timestamp at which the vesting expires |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | uint256 The ID of the derivative token |
_computeNameAndSymbol
Computes the name and symbol of a derivative token
function _computeNameAndSymbol(
ERC20 base_,
uint48 expiry_
) internal view returns (string memory, string memory);
Parameters
Name | Type | Description |
---|---|---|
base_ | ERC20 | The address of the underlying token |
expiry_ | uint48 | The timestamp at which the vesting expires |
Returns
Name | Type | Description |
---|---|---|
<none> | string | string The name of the derivative token |
<none> | string | string The symbol of the derivative token |
_deployIfNeeded
Deploys the derivative token if it does not already exist
If the derivative token does not exist, it will be deployed using a token id computed from the parameters.
function _deployIfNeeded(
address underlyingToken_,
VestingParams memory params_,
bool wrapped_
) internal returns (uint256 tokenId_, address wrappedAddress_);
Parameters
Name | Type | Description |
---|---|---|
underlyingToken_ | address | The address of the underlying token |
params_ | VestingParams | The parameters for the derivative token |
wrapped_ | bool | Whether or not to wrap the derivative token |
Returns
Name | Type | Description |
---|---|---|
tokenId_ | uint256 | The ID of the derivative token |
wrappedAddress_ | address | The address of the wrapped derivative token |
_deployWrapIfNeeded
Deploys the wrapped derivative token if it does not already exist
If the wrapped derivative token does not exist, it will be deployed
function _deployWrapIfNeeded(
uint256 tokenId_,
Token storage token_
) internal returns (address wrappedAddress);
Parameters
Name | Type | Description |
---|---|---|
tokenId_ | uint256 | The ID of the derivative token |
token_ | Token | The metadata for the derivative token |
Returns
Name | Type | Description |
---|---|---|
wrappedAddress | address | The address of the wrapped derivative token |
name
Returns the name of the token
This function reverts if:
- The token ID does not exist
function name(
uint256 tokenId_
) public view override onlyValidTokenId(tokenId_) returns (string memory);
Parameters
Name | Type | Description |
---|---|---|
tokenId_ | uint256 | The ID of the token |
Returns
Name | Type | Description |
---|---|---|
<none> | string | string The name of the token |
symbol
Returns the symbol of the token
This function reverts if:
- The token ID does not exist
function symbol(
uint256 tokenId_
) public view override onlyValidTokenId(tokenId_) returns (string memory);
Parameters
Name | Type | Description |
---|---|---|
tokenId_ | uint256 | The ID of the token |
Returns
Name | Type | Description |
---|---|---|
<none> | string | string The symbol of the token |
decimals
Returns the number of decimals used by the token
This function reverts if:
- The token ID does not exist
function decimals(
uint256 tokenId_
) public view override onlyValidTokenId(tokenId_) returns (uint8);
Parameters
Name | Type | Description |
---|---|---|
tokenId_ | uint256 | The ID of the token |
Returns
Name | Type | Description |
---|---|---|
<none> | uint8 | uint8 The number of decimals used by the token |
tokenURI
Returns the URI of the token
This function reverts if:
- The token ID does not exist
function tokenURI(
uint256 tokenId_
) public view override onlyValidTokenId(tokenId_) returns (string memory);
Parameters
Name | Type | Description |
---|---|---|
tokenId_ | uint256 | The ID of the token |
Returns
Name | Type | Description |
---|---|---|
<none> | string | string The URI of the token |