Skip to content
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 - DynamicFeeHook #101

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

Conversation

luizpf29
Copy link

The Dynamic Fee Hook contract is a smart extension to the Balancer protocol, created with the purpose of dynamically adjusting swap fees based on market conditions, specifically volatility and liquidity levels. This contract not only helps to stabilize the pools but also maximizes the rewards for those who provide liquidity. It brings benefits to both liquidity providers and token holders.

Copy link

vercel bot commented Oct 18, 2024

@luizpf29 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.

Copy link

@jubeira jubeira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your submission @luizpf29, great job!

This is a pretty cool idea. I've done a first pass (no need to address the comments; it's just for our internal review process).

I would have liked to see a test end to end, with the hook plugged in to a pool, trigger a few swaps, collect fees, and seeing what happens with the lending markets. But I also understand it's a fair amount of work, and you've already done quite a bit to get here.

We're going through the review process of all the submissions; it'll take a little longer. Thanks again for the submission and for your patience!

Comment on lines +135 to +136
uint256 calculatedSwapFeePercentage = deductibleHookFeePercentage + staticSwapFeePercentage;
// Charge the static or calculated fee, whichever is greater.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should always be the case, given that calculatedSwapFeePercentage = deductibleHookFeePercentage + staticSwapFeePercentage and everything is unsigned.

Comment on lines +226 to +231
// Calculate current liquidity (sum of all token balances in the pool)
uint256 totalLiquidity = 0;
for (uint256 i = 0; i < poolBalances.length; i++) {
totalLiquidity += poolBalances[i];
}
newLiquidity = totalLiquidity;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this makes sense if the pool is linear, but otherwise I think what you're looking for is the invariant.

The total liquidity doesn't necessarily reflect the "value" in the pool. E.g. in a 80/20 pool with 10 tokens A (80% weight) and 10000 tokens B (20% weight) means that those 10 tokens A make up 80% of the value of the pool (in other words, they are far more valuable per unit than the token B).

Computing the invariant would give you a better measure of the value stored in the pool.


function _calculateDynamicFee(uint256 _volatility, uint256 _liquidity) internal view returns (uint256) {
// Avoid division by zero
if (_liquidity == 0) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can just revert here; shouldn't happen anyways if you use the invariant.

) public override returns (bool success, uint256[] memory hookAdjustedAmountsInRaw) {
if (poolInfo[_pool].feeToken == address(0)) return (false, amountsInRaw);

address userAddress = IRouterCommon(router).getSender();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine, but it's pending a step.

Anyone can write their own router, and they might return wrong senders. So the hook should have a list of trusted routers, and only if you trust the router you can proceed to call getSender.

emit InvestPoolAdded(_pool, _asset);
}

function setEarlyUnlock(bool _allowedEarlyUnlock) external onlyOwner {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants