Building no-code token management tools to empower web3 founders and investors, starting with token vesting.
Platform: Code4rena
Start Date: 20/09/2022
End Date: 23/09/2022
Period: 3 days
Status: Completed
Pot Size: $30,000 USDC
Participants: 198
Reporter: liveactionllama
Judge: 0xean
Id: 164
League: ETH
pashov | 1/198 | $3,561.20 | 3 | 0 | 0 | 3 | 1 | 0 | 0 | 0 |
sorrynotsorry | 2/198 | $3,030.46 | 2 | 0 | 0 | 1 | 1 | - | 0 | 0 |
Respx | 3/198 | $1,611.82 | 4 | 0 | 0 | 2 | 0 | - | - | 0 |
fatherOfBlocks | 4/198 | $1,383.17 | 3 | 0 | 0 | 1 | 0 | - | - | 0 |
m9800 | 5/198 | $1,364.31 | 2 | 0 | 0 | 1 | 0 | 0 | - | 0 |
wagmi | 6/198 | $1,355.96 | 2 | 0 | 0 | 2 | 0 | 0 | 0 | 0 |
CertoraInc | 7/198 | $865.93 | 6 | 1 | 0 | 3 | 0 | - | - | 0 |
csanuragjain | 8/198 | $805.45 | 4 | 0 | 0 | 2 | 0 | - | - | 0 |
TomJ | 9/198 | $794.92 | 4 | 1 | 0 | 1 | 0 | - | - | 0 |
hansfriese | 10/198 | $636.42 | 3 | 1 | 0 | 1 | 0 | - | 0 | 0 |
Auditor per page
VTVL is a token management platform for web3 founders.
The core function of VTVL is to allow users to generate and deploy token vesting smart contracts through our platform.
This folder contains the vesting (and other auxiliary) smart contracts used for vtvl vesting project. It is set up within a hardhat
environment, so the usual hardhat
tools are available.
A very basic, standard ERC20 token (import from @openzeppelin ERC20.sol). Used as a helper for development. VTVLVesting contract supports any ERC20 token, so any other token can be substituted for this one.
A very basic, standard ERC20 token with the ability to premint some or all of the tokens. Furthermore, it allows the user to specify a variable supply later on, if required.
A contract to add and govern the admin access control to the main contract.
This is the main contract of the project. It controls the vesting of a given token, based on an arbitrary schedule.
When the contract is created (in the constructor), it receives the address for the relevant ERC20 token. This address cannot be changed later, i.e. a given contract can only control one token.
A vesting contract is associated to a token given at creation. It only carries out operations with respect to that token.
A claim is a vesting right associated to a given address. Each address can have a maximum of one claim associated to it.
A claim consists of the cliff part and the linear vesting part.
The cliff gets released all at once at a specified moment (cliffReleaseTimestamp).
Linear vesting, on the other hand, starts at startTimestamp and ends at some later date (endTimestamp). During this period, the user's allocation gradually increases as the time passes. The allocated amount can be configured to be claimable continuously (every second), or less frequently (for example, every hour, every day, etc).
Each of the parts (cliff and linear) have amounts that can be allocated to each. The founders can opt to use either or both options for each of the claims.
There are three main groups that may want to interact with the contract - the administrators, vesting recipients, and everyone else.
The administrators are normally the founders. They can create and revoke claims at will - however (other than revoking it), they cannot modify an existing claim. They can also withdraw the remaining amount not allocated on claims back to their wallet.
This group initially starts with just having the contract deployer as the owner/admin. They can then add (or remove) other users as administrators, relegating them the same rights.
If an user has a valid claim associated to their address, they have the ability to withdraw the amount that's claimable at the moment they make the claim. No one other than the designated vesting recipient (not even the admin) can withdraw on an existing claim - but the admin can revoke the claim.
Everyone else has just read access to the contract. That includes the ability to read all the vesting recipients, all claim information, as well as the information about how much will a given user vest at a certain point in time.
As part of the business logic, the vesting contract is designed to provide a trustless and automatic way to establish token vesting mechanism through locking tokens inside the vesting smart contract. However, due of the nature of vesting, e.g. employee token vesting, our vesting contract is deliberately designed to allow admin revocation in the circumstances of early employment termination (before the end of vesting period specified).
We understand that by allowing admins to have the ultimate power of revoking claims is a dangerous and centralised move in the design, we still think that this revocation design would match the business reality closer. We have added additional event
(ClaimRevoked
and AdminWithdrawn
) as counteraction(s) to keep admin's (revocation) actions transparent and (hopefully accountable) thanks to blockchain's immutable and permissionless nature.
Therefore any potential risks or attack vectors concerning unauthorised access to admin account(s) (e.g. lost of admin's private key) <u>will not</u> be considered as valid risk findings.
nodejs
, refer to nodejsyarn
, refer to yarnyarn install
in workspace root folderThe contracts can be compiled by running:
npx hardhat compile
This creates the appropriate artifacts.
npx hardhat node
Spins up a local node, similar to ganache. The private keys will be shown in the command line.
A full set of unit tests are provided in the test
folder
Runs the tests.
npx hardhat test