Vesting

Vesting contract is a smart contract that locks up funds for a period of time and allows the owner to withdraw the funds after the lockup period.

When a new employee joins an organization, they typically receive a promise of compensation to be disbursed after a specified duration of employment. This arrangement often involves the organization depositing the funds into a vesting contract, with the employee gaining access to the funds upon the completion of a predetermined lockup period. Through the utilization of vesting contracts, organizations establish a mechanism to encourage employee retention by linking financial rewards to tenure.

There are 2 actions (or endpoints) available to interact with this smart contract:

  • deposit asset
  • withdraw asset

To initialize the escrow, we need to initialize a provider, MeshTxBuilder and MeshVestingContract.

import { BlockfrostProvider, MeshTxBuilder } from '@meshsdk/core';
import { MeshVestingContract } from '@meshsdk/contracts';
import { useWallet } from '@meshsdk/react';

const { connected, wallet } = useWallet();

const blockchainProvider = new BlockfrostProvider(APIKEY);

const meshTxBuilder = new MeshTxBuilder({
  fetcher: blockchainProvider,
  submitter: blockchainProvider,
});

const contract = new MeshVestingContract({
  mesh: meshTxBuilder,
  fetcher: blockchainProvider,
  wallet: wallet,
  networkId: 0,
});

Both on-chain and off-chain codes are open-source and available on Mesh Github Repository.

Deposit Fund

Party A will deposit funds into the vesting contract, defining the locking period and the beneficiary address.

depositFund() deposit funds into a vesting contract. The function accepts the following parameters:

  • assets (Asset[]) - a list of assets
  • lockUntilTimeStampMs (number) - timestamp in milliseconds
  • beneficiary (string) - address of the beneficiary

We will deposit 8 ADA to the vesting contract. This vesting period is 1 minute and the beneficiary address is: addr_test1qpvx0...u0nq93swx9.

const assets: Asset[] = [
  {
    unit: 'lovelace',
    quantity: '8000000',
  },
];

const lockUntilTimeStamp = new Date();
lockUntilTimeStamp.setMinutes(lockUntilTimeStamp.getMinutes() + 1);

const beneficiary = 'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9';

const tx = await contract.depositFund(
  assets,
  lockUntilTimeStamp.getTime(),
  beneficiary
);

const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);

Withdraw Fund

After the lockup period has expired, the beneficiary can withdraw the funds from the vesting contract.

withdrawFund() withdraw funds from a vesting contract. The function accepts the following parameters:

  • vestingUtxo (UTxO) - unspent transaction output in the script

For this demo, we withdraw funds from the vesting contract with Mesh's "solution" wallet, the recipient of this vesting demo.

const utxo = await contract.getUtxoByTxHash(txHashToSearchFor);
const tx = await contract.withdrawFund(utxo);
const signedTx = await wallet.signTx(tx, true);
const txHash = await wallet.submitTx(signedTx);