Vote escrow architecture
Plenty's "ve" architecture
PLYtoken is based on the FA1.2 standard on Tezos.
PLYholders can lock their
PLYfor an integral number of weeks between 1 and 208. The Lock-up period is rounded up to the nearest whole week as
(Expiry // Week) * Week, so the lock period can be slightly (always < 7 days) higher or lower than the number of days your chosen number of weeks resolve to.
Locking is done by calling the
create_lockentrypoint in the
VoteEscrowcontract. The entrypoint pulls the required number of
PLYfrom the user balance and returns a
vePLYNFT that represents the lock.
vePLYNFT has an associated voting power that is linearly decreasing as
bias - slope * t. The slope is calculated based on your
PLYlock-up value and lock-up period.
At its core, the
VoteEscrowcontract is based on the FA2 standard. It maintains a
ledgerthat keeps track of the ownership of all
vePLYNFTs. Only the owner of a
vePLYNFT can unlock it after expiry and redeem the underlying PLY tokens by calling the
vePLYholder can vote on the distribution of weekly
PLYemission across the different
gauges, and in return collect fees and bribes for the AMM they vote for. Besides, the holder can also claim inflation for their locked
PLY, that is proportional to the global supply inflation. This is required in order to prevent dilution of locked stake overtime.
vePLYNFT has voting power that can be retrieved through the
get_token_voting_poweronchain view in the
VoteEscrowcontract. The voting power can be distributed as voting weights across different gauges the owner is intending to receive fees from and direct emissions to.
Voting is handled by the
VePLYholders can call the
voteentrypoint at each epoch to distribute their voting power (i.e vote) for the liquidity pools of their choice.
An epoch is a voting period that is a week long and ideally starts at every Thursday, 12 AM (UTC). When a
vePLYholder votes, their voting power at 12 AM (UTC) on the past Thursday is used.
When an epoch ends, the next epoch can be started by anyone calling the
next_epochentrypoint in the
Votercontract. Besides updating the epoch, this entrypoint also calculates and updates current
PLYinflation value, and adds a proportional inflation to the
To claim bribes and trading fees for a specific epoch, the
vePLYholder (who has voted) can call the
claim_feesentrypoints respectively, in
Voter. These entrypoints send internal transactions to
Bribecontract, and they in turn transfer the required amount to the holder.
To claim inflation, the holder can call
VoteEscrow, once for every epoch. The inflation is added directly to the underlying lock with the bias and slope being adjusted.
AMM Liquidity Providers can stake their LP tokens in the gauge associated with their AMM and receive
gaugecontracts essentially acts like a farms. Every week, the
recharge_gaugeentrypoint of the
Votercontract can be called to recharge a specific gauge, based on the emissions and gauge weights of the last epoch.
Stakers can also boost their emission rewards by a maximum of 2.5x by attaching a
vePLYNFT that they own, to their stake. Boosting is achieved using the following formula:
MIN(Staked-Balance, (0.4 * Staked-Balance) + (0.6 * Staked-Supply * Voting-power-of-vePLY / Total-voting-power))
An individual or even a protocol can bribe i.e essentially reward those who vote for a pool of their preference in a particular epoch.
Every AMM has an associated
Bribecontract that handles the process. Bribes can be given in any FA1.2 or FA2 standard based token by calling the
CoreFactorycontract has control over addition/deletion of AMMs in the vote-escrow system. The factory is controlled by a multisig.
When a new AMM is added, the associated
Bribecontracts are deployed and the AMM and it's token pair is stored in the
In order to calculate the voting power of a specific
vePLYNFT, or the global voting power at any timestamp t, we record checkpoints whenever any operation related to the vote escrow mechanism takes place. These operations include the creations of locks, increments of lock value and increments of lock period.
These checkpoints are recorded in the
global_checkpointsbigmap. Further to keep track of lock expiry, we keep the
To find the voting power at any specific timestamp, we binary search through the checkpoints to a timestamp closest to required, and extrapolate the values stored in the checkpoint to calculate voting power at the given timestamp.
The staked balance of the user is dialled down and kept in the range 40%-100% of the initial balance. This is stored as
derived_balancesand its associated
derived_supply. The dialing down is achieved using the formula stated in the AMM Liquidity Provider section. The derived values are further used to calculate the emission share.
For stakers who do not attach a
vePLYNFT to their stake, their derived balance is always 40% of the staked balance. To get maximum out of their stake i.e a 2.5x boost, they have to attach a
vePLYNFT with enough voting power to their stake.
vePLYNFT is attached to an LP stake in a particular gauge, it becomes un-transferrable and cannot be used as boost in any other gauge.
The operations in the
vePLYsystem require a ton of arithmetic calculations to be made on timestamps. Since Michelson
timestampis not versatile when it comes to arithmetic calculations,
natis chosen at the primary type to store UNIX timestamp values.