-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BAL Hookathon - VolatilityLoyaltyHook #105
base: main
Are you sure you want to change the base?
Conversation
Someone is attempting to deploy a commit to the Matt Pereira's projects Team on Vercel. A member of the Team first needs to authorize it. |
Hey @MattPereira would it be possible for you to review the code? |
Hey @dilawari2008 my apologies but the complexity of this hook is beyond my capacity to confidently evaluate. The way the volatility fee percentage is calculated by the I can opine that writing a hook this complex without any tests that verify it works as intended makes it more difficult for us review / trust the code. I have requested that a more experienced dev that was around for v2 take a look |
Ok, thanks @MattPereira . |
Volatility and Loyalty Hook for Balancer V3 Hackathon
Video explanation - https://www.loom.com/share/4b8b9b2685274af0864ac27887782196?sid=54923331-f288-40d1-9344-387905874e4f
Video demo - https://www.loom.com/share/defa9c16751e401d92daf6d5ed7d6b0d?sid=9a36b6bf-e3a4-4647-a955-71868bae7e78
The Volatility and Loyalty Hook aims to stimulate trading activity in a newly launched pool on Balancer by rewarding users with discounts on swap fees when they hold project tokens for a longer duration. It simultaneously ensures stability by increasing swap fees during periods of high volatility.
Contents
Hook Lifecycle Points
onAfterRemoveLiquidity(), onAfterAddLiquidity():
Updates the new token price in the Volatility Oracle along with the timestamps.
onAfterSwap():
Updates the new token price in the Volatility Oracle along with the timestamps.
Updates the loyalty index of the user.
onComputeDynamicSwapFeePercentage():
Calculates the swap fee based on the pool's volatility and the user's loyalty index.
Swap Fee Calculation
The swap fee is calculated as the sum of the swapFeeWithLoyaltyDiscount and the volatilityFee.
Swap Fee with Loyalty Discount
This reduces the static swap fee but maintains a minimum fee and a cap on the loyalty discount to prevent exploitation by large holders (whales).
Let’s assume
MAX_LOYALTY_FEE = 1%
. The logic is as follows:If
staticSwapFee <= 1%
:swapFeeWithLoyaltyDiscount = staticSwapFee
If
1% < staticSwapFee < 2%
(1% +MAX_LOYALTY_FEE
):swapFeeWithLoyaltyDiscount = 1% + (staticSwapFee - 1%) * (1 - loyaltyPercentage)
If
staticSwapFee == 2%
(1% +MAX_LOYALTY_FEE
):swapFeeWithLoyaltyDiscount = 1% + MAX_LOYALTY_FEE * (1 - loyaltyPercentage)
Else:
swapFeeWithLoyaltyDiscount = 1% + MAX_LOYALTY_FEE * (1 - loyaltyPercentage) + (staticSwapFee - 1% - MAX_LOYALTY_FEE)
Loyalty Percentage Calculation
We calculate a loyaltyIndex based on the time the tokens have been held, preventing flash loan attacks:
newLoyaltyIndex = previousLoyaltyIndex + (tokens held at the previous transaction) * (current timestamp - previous swap transaction timestamp)
Using this loyaltyIndex, we calculate the loyaltyPercentage through a tier-based system.
The loyalty index is refreshed if the previous transaction occurred more than _LOYALTY_REFRESH_WINDOW (30 days) ago.
Volatility Fee
volatilityFee = MAX_VOLATILITY_FEE * volatilityPercentage
Volatility Percentage Calculation
Note - The price oracle approach using a circular buffer was inspired from the implementation of the same in balancer v2; the code used from that section has been put in a separate folder balancer-v2-oracle.
Reference
Etherscan
The volatility percentage is calculated using a circular buffer to maintain a history of price and timestamp objects. The buffer ensures price updates are stored at intervals of, for example, 2 minutes ( a shorter duration for demo purposes). If an update occurs within this interval, the previous entry is overwritten; if it occurs later, a new entry is added.
Once the prices over a span of time are captured, the price 1 hour ago ( a shorter duration for demo purposes) is extracted using binary search from the oracle.
The formula for calculating volatility is:
** correction in the below diagram the inner bracket is to be sqaured (^2).
Where:
The unit of volatility is % price change per second. A tier-based system is then used to calculate the volatility fee percent.
DevX
Overall the developer experience was good. The documentation and examples are a good starting point. For more specific issues, the team was proactive on discord.