Flash protocol is an on-chain Ethereum Blockchain protocol. The protocol enables users to stake tokens and earn rewards immediately. Staking is not new, however, in different protocols, the staking process is different or users earn incentives in a different manner. Such as sBTC staking, where users have to provide ETH/sBTC both, or AMPL on which you can stake your LP tokens and earn AMPL tokens as a reward.
Users deposit their $FLASH for a duration and earn an upfront reward in terms of $FLASH.
Users specify the staking duration themselves, then the reward $FLASH is minted and transferred to the recipient’s address.
Before the reward amount, the protocol calculates $FLASH per Yield (FPY), which is the amount of annual reward that the user will receive in percentage.
To actually limit users from getting 100% on return of their staked amount, FPY is restricted to 50% by dividing the value by 2. The duration must not be less than 0 and must not exceed the maximum stake period. The maximum stake period is dependent upon the FPY.
Where maximum FPY in a year is 50%, seconds in a year are equivalent to the multiple of 365 and 86400 i.e. 31536000 seconds.
The relation between FPY and maximum stake period is inversely proportional. If the FPY is maximum i.e. 50%, then the max stake period would be 1 year. If the FPY is minimum i.e. 1%, then the max stake period would be 50 years.
The upfront reward is minted using the formula:
In the flash protocol, the user can set the recipient address. This can be an EOA or some contract as well. Enabling users to stake for other people as well. If the recipient is a contract, then the data parameter is also passed in the stake function.
Apart from minting the stake reward, Blockzero also receives a reward amount. This reward amount is calculated using the formula:
Match amount i.e. foundation’s reward, is [0-20]% of the totalSupply. This amount is transferred to matchReceiever address. This amount mints when the user stakes $FLASH.
The contract store staker’s id, which is a hash of staked amount, duration, receiver’s and staker’s addresses, and block.timestamp. The staker’s address and block.timestamp makes sure that a staker can stake once per block with the same data. This prevents staker to attack our protocol with repetitive stakes.
Once the staking duration expires users can unstake their $FLASH. Once the balance is withdrawn the stake id is deleted to empty space in EVM. The deletion of space on EVM saves gas and space by removing redundant empty stakes.
The unstake function is not restricted only to staker. If someone wants to unstake on behalf of the staker, they may do so, but the unstake amount will be sent to the staker’s address.
Users can withdraw staked $FLASH before the duration expires. As the user receives an upfront reward on staking. On unstaking early, a portion of the staked amount is burned. The calculation of burnAmount needs inverse of FPY, which is calculated using:
This amount of tokens that will burn is calculated with:
It is possible for the user to burn 100% of the staked amount. The relation between inverse FPY and early unstake is directly proportional. If more tokens are staked from totalSupply then the user will burn more tokens as inverse FPY can get near to 100%.
The protocol has matchRatio earnings. The current matchRatio for the protocol is 20%. The matchRatio can be 0 but cannot be more than 20% of the totalSupply. The matchReceiver, a pre-specified address, can set the matchRatio to a different value. Also, matchRatio cannot change overnight. Once the setMatchRatio is triggered, the protocol will take 3 days before using the new value of matchRatio.
The matchReceiver can call setMatchReceiver to change the address of matchReceiver itself. This change also comes into action after 3 days.
The protocol also has the functionality to prevent the value of matchRation and/or matchReceiver from changing. The lock duration is the maximum amount of uint256 storage which is 2**256-1.
If the receiver address is a contract address. Then the contract must implement the IFLASHReceiver interface and receiveFlash function. By doing so, users may build dApps. These dApps will utilize the reward amount in their functionalities.
Flashstake dApp is built using the Flash protocol. The dApp implements the IFlashReceiver interface and the receiveFlash function. Users can stake or swap their tokens using this dApp. The flashstake is built using AMM, which is based on the xyk model.
Liquidity providers earn a fee which the users pay. LP fees are dependent on FPY, the higher the FPY, the higher will be the LP fees and vise versa.
Here, the FPY max in a year is 50%.
On every trade, the LPFee in percentage is calculated with:
Whentokendoesn’t have a pool pair with $FLASH. Flashstake dApp enables users to create pools. It uses the Create2 library which facilitates the create2 EVM opcode by making it easier and safer.
Users can stake $FLASH and receive any other ALT tokens required that the pair pool exists. The ALT tokens which the users want and the expected amount is entered as the data parameter of receiveFlash function.
Otherwise, the users receive the ALT tokens, and then reserves are updated. This ALT quantity is based on:
The swap functionality in Flashstake dApp, enables users to receive $FLASH for any ALT tokens.
The formula calculates the amount of $FLASH which the user receives then reserves are updated.
Users unstake the staked $FLASH using this functionality. The Unstake function of Flash dApp essentially triggers the flash protocol, which we discussed in section 1.1.3 & 1.1.4
The expectedOutput condition applies for swap functionality as well as stake functionality. Expected output refers to the minimum amount of tokens the user is expecting. If the amount goes below the value of expectedOutput, the transaction is reverted.
Anyone can become a liquidity provider, LP, for a pool by depositing an equivalent value of each $FLASH and ALT pool in return for LP tokens. These LP Tokens represent the share of the pool owned by LPs.
When LP provides liquidity for the first time, the shares equal to the geometric mean of the deposited amounts are minted. Furthermore, Flash protocol burns 1000 times of the minimum quantity of pool shares to raise the value of minimum liquidity tokens.
When a new liquidity provider deposits tokens into an existing pool, the number of liquidity tokens minted is computed based on the existing quantity of tokens:
When the liquidity providers attempt to withdraw liquidity. The LP tokens in their possession are burned and the $FLASH and ALT tokens they deposited are transferred to their address.
Flash dApp allows users to authorize a transfer of their pool shares with a signature. Anyone can submit this signature on the authorizer’s behalf by calling the permit function, paying gas fees, and possibly performing other actions in the same transaction.
The protocol removes the approval transaction to remove liquidity from their app. Hence the UX is improved and users’ gas fee is also saved.
$FLASH tokens are the native, ERC-20 tokens for Flash protocol. As mentioned above, $FLASH tokens can be used for staking and can be earned by swapping ALT.
The total supply of $FLASH is not fixed. As new $FLASH are minted and burned in Flash protocol, the amount of total supply varies. See section 1.1.1, 1.1.2, and 1.1.3
The permit function approves the spender to spend owners tokens. This is made possible with meta transactions. The owner provides a signature to the spender. Then the spender can approve its address. Hence, getting the permit.
The transferWithAuthorization function authorized the spender to transfer the owner’s tokens. This also requires the owner’s signature.
Read about Uniswap in our article