-
Notifications
You must be signed in to change notification settings - Fork 7
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
Gyroscope AMM adapter & Gyroscope Aura Farm #141
base: main
Are you sure you want to change the base?
Conversation
function _approveIfNeeded(address token, uint amount, address spender) internal { | ||
if (IERC20(token).allowance(address(this), spender) < amount) { | ||
// infinite approve, 2*255 is more gas efficient then type(uint).max | ||
IERC20(token).forceApprove(spender, 2 ** 255); | ||
} | ||
} |
Check warning
Code scanning / Slither
Dead-code Warning
function _getTokensIndexes( | ||
address pool, | ||
address tokenIn, | ||
address tokenOut | ||
) internal view returns (int128 tokenInIndex, int128 tokenOutIndex) { | ||
address[] memory tokens = poolTokens(pool); | ||
uint len = tokens.length; | ||
for (uint i; i < len; ++i) { | ||
if (tokenIn == tokens[i]) { | ||
tokenInIndex = int128(uint128(i)); | ||
} | ||
if (tokenOut == tokens[i]) { | ||
tokenOutIndex = int128(uint128(i)); | ||
} | ||
} | ||
} |
Check warning
Code scanning / Slither
Dead-code Warning
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Semgrep OSS found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.
function getPrice(address pool, address tokenIn, address tokenOut, uint amount) public view returns (uint) { | ||
// return IGyroECLPPool(pool).getPrice(); | ||
|
||
bytes32 poolId = IBWeightedPoolMinimal(pool).getPoolId(); | ||
(IERC20[] memory tokens, uint[] memory balances,) = IBVault(balancerVault).getPoolTokens(poolId); | ||
|
||
bool tokenInIsToken0 = tokenIn == address(tokens[0]); | ||
(GyroECLPMath.Params memory eclpParams, GyroECLPMath.DerivedParams memory derivedECLPParams) = | ||
IGyroECLPPool(pool).getECLPParams(); | ||
GyroECLPMath.Vector2 memory invariant; | ||
{ | ||
(int currentInvariant, int invErr) = | ||
GyroECLPMath.calculateInvariantWithError(balances, eclpParams, derivedECLPParams); | ||
// invariant = overestimate in x-component, underestimate in y-component | ||
// No overflow in `+` due to constraints to the different values enforced in GyroECLPMath. | ||
invariant = GyroECLPMath.Vector2(currentInvariant + 2 * invErr, currentInvariant); | ||
} | ||
|
||
return GyroECLPMath.calcOutGivenIn(balances, amount, tokenInIsToken0, eclpParams, derivedECLPParams, invariant); | ||
} |
Check warning
Code scanning / Slither
Unused return Medium
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #141 +/- ##
===========================================
- Coverage 98.04% 84.55% -13.50%
===========================================
Files 62 71 +9
Lines 4562 5290 +728
Branches 489 619 +130
===========================================
Hits 4473 4473
- Misses 81 809 +728
Partials 8 8 ☔ View full report in Codecov by Sentry. |
uint amountIn = IERC20(tokenIn).balanceOf(address(this)); | ||
|
||
// Initializing each struct field one-by-one uses less gas than setting all at once. | ||
IBVault.FundManagement memory funds; |
Check warning
Code scanning / Slither
Uninitialized local variables Medium
funds.toInternalBalance = false; | ||
|
||
// Initializing each struct field one-by-one uses less gas than setting all at once. | ||
IBVault.SingleSwap memory singleSwap; |
Check warning
Code scanning / Slither
Uninitialized local variables Medium
function poolTokens(address pool) public view returns (address[] memory) { | ||
bytes32 poolId = IBWeightedPoolMinimal(pool).getPoolId(); | ||
(IERC20[] memory tokenContracts,,) = IBVault(balancerVault).getPoolTokens(poolId); | ||
address[] memory tokens = new address[](tokenContracts.length); | ||
for (uint i; i < tokenContracts.length; ++i) { | ||
tokens[i] = address(tokenContracts[i]); | ||
} | ||
return tokens; | ||
} |
Check warning
Code scanning / Slither
Unused return Medium
function swap( | ||
address pool, | ||
address tokenIn, | ||
address tokenOut, | ||
address recipient, | ||
uint priceImpactTolerance | ||
) external { | ||
uint amountIn = IERC20(tokenIn).balanceOf(address(this)); | ||
|
||
// Initializing each struct field one-by-one uses less gas than setting all at once. | ||
IBVault.FundManagement memory funds; | ||
funds.sender = address(this); | ||
funds.fromInternalBalance = false; | ||
funds.recipient = payable(recipient); | ||
funds.toInternalBalance = false; | ||
|
||
// Initializing each struct field one-by-one uses less gas than setting all at once. | ||
IBVault.SingleSwap memory singleSwap; | ||
singleSwap.poolId = IBWeightedPoolMinimal(pool).getPoolId(); | ||
singleSwap.kind = IBVault.SwapKind.GIVEN_IN; | ||
singleSwap.assetIn = IAsset(address(tokenIn)); | ||
singleSwap.assetOut = IAsset(address(tokenOut)); | ||
singleSwap.amount = amountIn; | ||
singleSwap.userData = ""; | ||
|
||
// scope for checking price impact | ||
uint amountOutMax; | ||
{ | ||
uint minimalAmount = amountIn / 1000; | ||
require(minimalAmount != 0, "Too low amountIn"); | ||
uint price = getPrice(pool, tokenIn, tokenOut, minimalAmount); | ||
amountOutMax = price * amountIn / minimalAmount; | ||
} | ||
|
||
IERC20(tokenIn).approve(balancerVault, amountIn); | ||
uint amountOut = IBVault(balancerVault).swap(singleSwap, funds, _LIMIT, block.timestamp); | ||
|
||
require( | ||
amountOutMax < amountOut | ||
|| (amountOutMax - amountOut) * ConstantsLib.DENOMINATOR / amountOutMax <= priceImpactTolerance, | ||
"!PRICE" | ||
); | ||
|
||
emit SwapInPool(pool, tokenIn, tokenOut, recipient, priceImpactTolerance, amountIn, amountOut); | ||
} |
Check warning
Code scanning / Slither
Unused return Medium
function swap( | ||
address pool, | ||
address tokenIn, | ||
address tokenOut, | ||
address recipient, | ||
uint priceImpactTolerance | ||
) external { | ||
uint amountIn = IERC20(tokenIn).balanceOf(address(this)); | ||
|
||
// Initializing each struct field one-by-one uses less gas than setting all at once. | ||
IBVault.FundManagement memory funds; | ||
funds.sender = address(this); | ||
funds.fromInternalBalance = false; | ||
funds.recipient = payable(recipient); | ||
funds.toInternalBalance = false; | ||
|
||
// Initializing each struct field one-by-one uses less gas than setting all at once. | ||
IBVault.SingleSwap memory singleSwap; | ||
singleSwap.poolId = IBWeightedPoolMinimal(pool).getPoolId(); | ||
singleSwap.kind = IBVault.SwapKind.GIVEN_IN; | ||
singleSwap.assetIn = IAsset(address(tokenIn)); | ||
singleSwap.assetOut = IAsset(address(tokenOut)); | ||
singleSwap.amount = amountIn; | ||
singleSwap.userData = ""; | ||
|
||
// scope for checking price impact | ||
uint amountOutMax; | ||
{ | ||
uint minimalAmount = amountIn / 1000; | ||
require(minimalAmount != 0, "Too low amountIn"); | ||
uint price = getPrice(pool, tokenIn, tokenOut, minimalAmount); | ||
amountOutMax = price * amountIn / minimalAmount; | ||
} | ||
|
||
IERC20(tokenIn).approve(balancerVault, amountIn); | ||
uint amountOut = IBVault(balancerVault).swap(singleSwap, funds, _LIMIT, block.timestamp); | ||
|
||
require( | ||
amountOutMax < amountOut | ||
|| (amountOutMax - amountOut) * ConstantsLib.DENOMINATOR / amountOutMax <= priceImpactTolerance, | ||
"!PRICE" | ||
); | ||
|
||
emit SwapInPool(pool, tokenIn, tokenOut, recipient, priceImpactTolerance, amountIn, amountOut); | ||
} |
Check notice
Code scanning / Slither
Block timestamp Low
Dangerous comparisons:
- require(bool,string)(amountOutMax < amountOut || (amountOutMax - amountOut) * ConstantsLib.DENOMINATOR / amountOutMax <= priceImpactTolerance,!PRICE)
Gyroscope AMM adapter
Gyroscope Aura Farm