-
Notifications
You must be signed in to change notification settings - Fork 8
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
SiL #223
base: main
Are you sure you want to change the base?
Conversation
function initVariants(address platform_) | ||
public | ||
view | ||
returns (string[] memory variants, address[] memory addresses, uint[] memory nums, int24[] memory ticks) | ||
{ | ||
IFactory.StrategyAvailableInitParams memory params = | ||
IFactory(IPlatform(platform_).factory()).strategyAvailableInitParams(keccak256(bytes(strategyLogicId()))); | ||
uint len = params.initNums[0]; | ||
variants = new string[](len); | ||
addresses = new address[](len * 2); | ||
nums = new uint[](0); | ||
ticks = new int24[](0); | ||
for (uint i; i < len; ++i) { | ||
address collateralAsset = IERC4626(params.initAddresses[i * 2]).asset(); | ||
address borrowAsset = IERC4626(params.initAddresses[i * 2 + 1]).asset(); | ||
variants[i] = _generateDescription(collateralAsset, borrowAsset); | ||
addresses[i * 2] = params.initAddresses[i * 2]; | ||
addresses[i * 2 + 1] = params.initAddresses[i * 2 + 1]; | ||
} | ||
} |
Check notice
Code scanning / Slither
Calls inside a loop Low
function initVariants(address platform_) | ||
public | ||
view | ||
returns (string[] memory variants, address[] memory addresses, uint[] memory nums, int24[] memory ticks) | ||
{ | ||
IFactory.StrategyAvailableInitParams memory params = | ||
IFactory(IPlatform(platform_).factory()).strategyAvailableInitParams(keccak256(bytes(strategyLogicId()))); | ||
uint len = params.initNums[0]; | ||
variants = new string[](len); | ||
addresses = new address[](len * 2); | ||
nums = new uint[](0); | ||
ticks = new int24[](0); | ||
for (uint i; i < len; ++i) { | ||
address collateralAsset = IERC4626(params.initAddresses[i * 2]).asset(); | ||
address borrowAsset = IERC4626(params.initAddresses[i * 2 + 1]).asset(); | ||
variants[i] = _generateDescription(collateralAsset, borrowAsset); | ||
addresses[i * 2] = params.initAddresses[i * 2]; | ||
addresses[i * 2 + 1] = params.initAddresses[i * 2 + 1]; | ||
} | ||
} |
Check notice
Code scanning / Slither
Calls inside a loop Low
function _generateDescription(address collateralAsset, address borrowAsset) internal view returns (string memory) { | ||
return string.concat( | ||
"Supply ", | ||
IERC20Metadata(collateralAsset).symbol(), | ||
" and borrow ", | ||
IERC20Metadata(borrowAsset).symbol(), | ||
" on Silo V2 with leverage looping" | ||
); | ||
} |
Check notice
Code scanning / Slither
Calls inside a loop Low
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #223 +/- ##
==========================================
+ Coverage 93.12% 93.29% +0.16%
==========================================
Files 91 93 +2
Lines 8296 8543 +247
Branches 708 721 +13
==========================================
+ Hits 7726 7970 +244
- Misses 534 537 +3
Partials 36 36 ☔ View full report in Codecov by Sentry. |
revert IControllable.IncorrectInitParams(); | ||
} | ||
|
||
LeverageLendingStrategyBaseInitParams memory params; |
Check warning
Code scanning / Slither
Uninitialized local variables Medium
function receiveFlashLoan( | ||
address[] memory tokens, | ||
uint[] memory amounts, | ||
uint[] memory feeAmounts, | ||
bytes memory /*userData*/ | ||
) external { | ||
// Flash loan is performed upon deposit and withdrawal | ||
|
||
LeverageLendingBaseStorage storage $ = _getLeverageLendingBaseStorage(); | ||
address flashLoanVault = $.flashLoanVault; | ||
if (msg.sender != flashLoanVault) { | ||
revert IControllable.IncorrectMsgSender(); | ||
} | ||
|
||
if ($.tempAction == CurrentAction.Deposit) { | ||
// tokens[0] is collateral asset | ||
uint tempBorrowAmount = $.tempBorrowAmount; | ||
|
||
// supply | ||
ISilo($.lendingVault).deposit(amounts[0], address(this), ISilo.CollateralType.Collateral); | ||
|
||
// borrow | ||
ISilo($.borrowingVault).borrow(tempBorrowAmount, address(this), address(this)); | ||
|
||
// swap | ||
_swap($.borrowAsset, tokens[0], tempBorrowAmount); | ||
|
||
// pay flash loan | ||
IERC20(tokens[0]).safeTransfer(flashLoanVault, amounts[0] + feeAmounts[0]); | ||
|
||
// reset temp vars | ||
$.tempBorrowAmount = 0; | ||
} | ||
|
||
if ($.tempAction == CurrentAction.Withdraw) { | ||
// tokens[0] is borrow asset | ||
address lendingVault = $.lendingVault; | ||
address collateralAsset = $.collateralAsset; | ||
uint tempCollateralAmount = $.tempCollateralAmount; | ||
|
||
// repay debt | ||
ISilo($.borrowingVault).repay(amounts[0], address(this)); | ||
|
||
// withdraw | ||
uint collateralAmountTotal = IERC4626(lendingVault).convertToAssets(StrategyLib.balance(lendingVault)); | ||
collateralAmountTotal -= collateralAmountTotal / 1000; | ||
ISilo(lendingVault).withdraw( | ||
Math.min(tempCollateralAmount, collateralAmountTotal), | ||
address(this), | ||
address(this), | ||
ISilo.CollateralType.Collateral | ||
); | ||
|
||
// swap | ||
_swap(collateralAsset, tokens[0], Math.min(tempCollateralAmount, StrategyLib.balance(collateralAsset))); | ||
|
||
// pay flash loan | ||
IERC20(tokens[0]).safeTransfer(flashLoanVault, amounts[0] + feeAmounts[0]); | ||
|
||
// swap unnecessary borrow asset | ||
_swap(tokens[0], collateralAsset, StrategyLib.balance(tokens[0])); | ||
|
||
// reset temp vars | ||
$.tempCollateralAmount = 0; | ||
} | ||
|
||
$.tempAction = CurrentAction.None; | ||
} |
Check warning
Code scanning / Slither
Unused return Medium
function receiveFlashLoan( | ||
address[] memory tokens, | ||
uint[] memory amounts, | ||
uint[] memory feeAmounts, | ||
bytes memory /*userData*/ | ||
) external { | ||
// Flash loan is performed upon deposit and withdrawal | ||
|
||
LeverageLendingBaseStorage storage $ = _getLeverageLendingBaseStorage(); | ||
address flashLoanVault = $.flashLoanVault; | ||
if (msg.sender != flashLoanVault) { | ||
revert IControllable.IncorrectMsgSender(); | ||
} | ||
|
||
if ($.tempAction == CurrentAction.Deposit) { | ||
// tokens[0] is collateral asset | ||
uint tempBorrowAmount = $.tempBorrowAmount; | ||
|
||
// supply | ||
ISilo($.lendingVault).deposit(amounts[0], address(this), ISilo.CollateralType.Collateral); | ||
|
||
// borrow | ||
ISilo($.borrowingVault).borrow(tempBorrowAmount, address(this), address(this)); | ||
|
||
// swap | ||
_swap($.borrowAsset, tokens[0], tempBorrowAmount); | ||
|
||
// pay flash loan | ||
IERC20(tokens[0]).safeTransfer(flashLoanVault, amounts[0] + feeAmounts[0]); | ||
|
||
// reset temp vars | ||
$.tempBorrowAmount = 0; | ||
} | ||
|
||
if ($.tempAction == CurrentAction.Withdraw) { | ||
// tokens[0] is borrow asset | ||
address lendingVault = $.lendingVault; | ||
address collateralAsset = $.collateralAsset; | ||
uint tempCollateralAmount = $.tempCollateralAmount; | ||
|
||
// repay debt | ||
ISilo($.borrowingVault).repay(amounts[0], address(this)); | ||
|
||
// withdraw | ||
uint collateralAmountTotal = IERC4626(lendingVault).convertToAssets(StrategyLib.balance(lendingVault)); | ||
collateralAmountTotal -= collateralAmountTotal / 1000; | ||
ISilo(lendingVault).withdraw( | ||
Math.min(tempCollateralAmount, collateralAmountTotal), | ||
address(this), | ||
address(this), | ||
ISilo.CollateralType.Collateral | ||
); | ||
|
||
// swap | ||
_swap(collateralAsset, tokens[0], Math.min(tempCollateralAmount, StrategyLib.balance(collateralAsset))); | ||
|
||
// pay flash loan | ||
IERC20(tokens[0]).safeTransfer(flashLoanVault, amounts[0] + feeAmounts[0]); | ||
|
||
// swap unnecessary borrow asset | ||
_swap(tokens[0], collateralAsset, StrategyLib.balance(tokens[0])); | ||
|
||
// reset temp vars | ||
$.tempCollateralAmount = 0; | ||
} | ||
|
||
$.tempAction = CurrentAction.None; | ||
} |
Check warning
Code scanning / Slither
Unused return Medium
function receiveFlashLoan( | ||
address[] memory tokens, | ||
uint[] memory amounts, | ||
uint[] memory feeAmounts, | ||
bytes memory /*userData*/ | ||
) external { | ||
// Flash loan is performed upon deposit and withdrawal | ||
|
||
LeverageLendingBaseStorage storage $ = _getLeverageLendingBaseStorage(); | ||
address flashLoanVault = $.flashLoanVault; | ||
if (msg.sender != flashLoanVault) { | ||
revert IControllable.IncorrectMsgSender(); | ||
} | ||
|
||
if ($.tempAction == CurrentAction.Deposit) { | ||
// tokens[0] is collateral asset | ||
uint tempBorrowAmount = $.tempBorrowAmount; | ||
|
||
// supply | ||
ISilo($.lendingVault).deposit(amounts[0], address(this), ISilo.CollateralType.Collateral); | ||
|
||
// borrow | ||
ISilo($.borrowingVault).borrow(tempBorrowAmount, address(this), address(this)); | ||
|
||
// swap | ||
_swap($.borrowAsset, tokens[0], tempBorrowAmount); | ||
|
||
// pay flash loan | ||
IERC20(tokens[0]).safeTransfer(flashLoanVault, amounts[0] + feeAmounts[0]); | ||
|
||
// reset temp vars | ||
$.tempBorrowAmount = 0; | ||
} | ||
|
||
if ($.tempAction == CurrentAction.Withdraw) { | ||
// tokens[0] is borrow asset | ||
address lendingVault = $.lendingVault; | ||
address collateralAsset = $.collateralAsset; | ||
uint tempCollateralAmount = $.tempCollateralAmount; | ||
|
||
// repay debt | ||
ISilo($.borrowingVault).repay(amounts[0], address(this)); | ||
|
||
// withdraw | ||
uint collateralAmountTotal = IERC4626(lendingVault).convertToAssets(StrategyLib.balance(lendingVault)); | ||
collateralAmountTotal -= collateralAmountTotal / 1000; | ||
ISilo(lendingVault).withdraw( | ||
Math.min(tempCollateralAmount, collateralAmountTotal), | ||
address(this), | ||
address(this), | ||
ISilo.CollateralType.Collateral | ||
); | ||
|
||
// swap | ||
_swap(collateralAsset, tokens[0], Math.min(tempCollateralAmount, StrategyLib.balance(collateralAsset))); | ||
|
||
// pay flash loan | ||
IERC20(tokens[0]).safeTransfer(flashLoanVault, amounts[0] + feeAmounts[0]); | ||
|
||
// swap unnecessary borrow asset | ||
_swap(tokens[0], collateralAsset, StrategyLib.balance(tokens[0])); | ||
|
||
// reset temp vars | ||
$.tempCollateralAmount = 0; | ||
} | ||
|
||
$.tempAction = CurrentAction.None; | ||
} |
Check warning
Code scanning / Slither
Unused return Medium
function receiveFlashLoan( | ||
address[] memory tokens, | ||
uint[] memory amounts, | ||
uint[] memory feeAmounts, | ||
bytes memory /*userData*/ | ||
) external { | ||
// Flash loan is performed upon deposit and withdrawal | ||
|
||
LeverageLendingBaseStorage storage $ = _getLeverageLendingBaseStorage(); | ||
address flashLoanVault = $.flashLoanVault; | ||
if (msg.sender != flashLoanVault) { | ||
revert IControllable.IncorrectMsgSender(); | ||
} | ||
|
||
if ($.tempAction == CurrentAction.Deposit) { | ||
// tokens[0] is collateral asset | ||
uint tempBorrowAmount = $.tempBorrowAmount; | ||
|
||
// supply | ||
ISilo($.lendingVault).deposit(amounts[0], address(this), ISilo.CollateralType.Collateral); | ||
|
||
// borrow | ||
ISilo($.borrowingVault).borrow(tempBorrowAmount, address(this), address(this)); | ||
|
||
// swap | ||
_swap($.borrowAsset, tokens[0], tempBorrowAmount); | ||
|
||
// pay flash loan | ||
IERC20(tokens[0]).safeTransfer(flashLoanVault, amounts[0] + feeAmounts[0]); | ||
|
||
// reset temp vars | ||
$.tempBorrowAmount = 0; | ||
} | ||
|
||
if ($.tempAction == CurrentAction.Withdraw) { | ||
// tokens[0] is borrow asset | ||
address lendingVault = $.lendingVault; | ||
address collateralAsset = $.collateralAsset; | ||
uint tempCollateralAmount = $.tempCollateralAmount; | ||
|
||
// repay debt | ||
ISilo($.borrowingVault).repay(amounts[0], address(this)); | ||
|
||
// withdraw | ||
uint collateralAmountTotal = IERC4626(lendingVault).convertToAssets(StrategyLib.balance(lendingVault)); | ||
collateralAmountTotal -= collateralAmountTotal / 1000; | ||
ISilo(lendingVault).withdraw( | ||
Math.min(tempCollateralAmount, collateralAmountTotal), | ||
address(this), | ||
address(this), | ||
ISilo.CollateralType.Collateral | ||
); | ||
|
||
// swap | ||
_swap(collateralAsset, tokens[0], Math.min(tempCollateralAmount, StrategyLib.balance(collateralAsset))); | ||
|
||
// pay flash loan | ||
IERC20(tokens[0]).safeTransfer(flashLoanVault, amounts[0] + feeAmounts[0]); | ||
|
||
// swap unnecessary borrow asset | ||
_swap(tokens[0], collateralAsset, StrategyLib.balance(tokens[0])); | ||
|
||
// reset temp vars | ||
$.tempCollateralAmount = 0; | ||
} | ||
|
||
$.tempAction = CurrentAction.None; | ||
} |
Check warning
Code scanning / Slither
Unused return Medium
function _claimRevenue() | ||
internal | ||
override | ||
returns ( | ||
address[] memory __assets, | ||
uint[] memory __amounts, | ||
address[] memory __rewardAssets, | ||
uint[] memory __rewardAmounts | ||
) | ||
{ | ||
__assets = assets(); | ||
__rewardAssets = new address[](0); | ||
__rewardAmounts = new uint[](0); | ||
__amounts = new uint[](1); | ||
|
||
LeverageLendingBaseStorage storage $ = _getLeverageLendingBaseStorage(); | ||
LeverageLendingAddresses memory v = LeverageLendingAddresses({ | ||
collateralAsset: $.collateralAsset, | ||
borrowAsset: $.borrowAsset, | ||
lendingVault: $.lendingVault, | ||
borrowingVault: $.borrowingVault | ||
}); | ||
StrategyBaseStorage storage $base = _getStrategyBaseStorage(); | ||
|
||
uint totalWas = $base.total; | ||
|
||
ISilo(v.lendingVault).accrueInterest(); | ||
ISilo(v.borrowingVault).accrueInterest(); | ||
|
||
uint totalNow = StrategyLib.balance(v.collateralAsset) + _calcTotal(v); | ||
if (totalNow > totalWas) { | ||
__amounts[0] = totalNow - totalWas; | ||
} | ||
$base.total = totalNow; | ||
//console.log('total was', totalWas); | ||
//console.log('total now', totalNow); | ||
} |
Check warning
Code scanning / Slither
Unused return Medium
function _claimRevenue() | ||
internal | ||
override | ||
returns ( | ||
address[] memory __assets, | ||
uint[] memory __amounts, | ||
address[] memory __rewardAssets, | ||
uint[] memory __rewardAmounts | ||
) | ||
{ | ||
__assets = assets(); | ||
__rewardAssets = new address[](0); | ||
__rewardAmounts = new uint[](0); | ||
__amounts = new uint[](1); | ||
|
||
LeverageLendingBaseStorage storage $ = _getLeverageLendingBaseStorage(); | ||
LeverageLendingAddresses memory v = LeverageLendingAddresses({ | ||
collateralAsset: $.collateralAsset, | ||
borrowAsset: $.borrowAsset, | ||
lendingVault: $.lendingVault, | ||
borrowingVault: $.borrowingVault | ||
}); | ||
StrategyBaseStorage storage $base = _getStrategyBaseStorage(); | ||
|
||
uint totalWas = $base.total; | ||
|
||
ISilo(v.lendingVault).accrueInterest(); | ||
ISilo(v.borrowingVault).accrueInterest(); | ||
|
||
uint totalNow = StrategyLib.balance(v.collateralAsset) + _calcTotal(v); | ||
if (totalNow > totalWas) { | ||
__amounts[0] = totalNow - totalWas; | ||
} | ||
$base.total = totalNow; | ||
//console.log('total was', totalWas); | ||
//console.log('total now', totalNow); | ||
} |
Check warning
Code scanning / Slither
Unused return Medium
function _depositAssets(uint[] memory amounts, bool /*claimRevenue*/ ) internal override returns (uint value) { | ||
LeverageLendingBaseStorage storage $ = _getLeverageLendingBaseStorage(); | ||
$.tempAction = CurrentAction.Deposit; | ||
LeverageLendingAddresses memory v = LeverageLendingAddresses({ | ||
collateralAsset: $.collateralAsset, | ||
borrowAsset: $.borrowAsset, | ||
lendingVault: $.lendingVault, | ||
borrowingVault: $.borrowingVault | ||
}); | ||
address[] memory _assets = assets(); | ||
uint valueWas = StrategyLib.balance(_assets[0]) + _calcTotal(v); | ||
|
||
(uint maxLtv,, uint targetLeverage) = _getLtvData(v.lendingVault, $.targetLeveragePercent); | ||
|
||
uint[] memory flashAmounts = new uint[](1); | ||
flashAmounts[0] = amounts[0] * targetLeverage / INTERNAL_PRECISION; | ||
|
||
(uint priceCtoB,) = _getPrices(ISilo(v.lendingVault).config(), v.lendingVault, v.borrowingVault); | ||
$.tempBorrowAmount = (flashAmounts[0] * maxLtv / 1e18) * priceCtoB / 1e18 - 2; | ||
|
||
IBVault($.flashLoanVault).flashLoan(address(this), _assets, flashAmounts, ""); | ||
|
||
uint valueNow = StrategyLib.balance(_assets[0]) + _calcTotal(v); | ||
|
||
if (valueNow > valueWas) { | ||
// deposit profit | ||
value = amounts[0] + (valueNow - valueWas); | ||
} else { | ||
// deposit loss | ||
value = amounts[0] - (valueWas - valueNow); | ||
} | ||
|
||
StrategyBaseStorage storage $base = _getStrategyBaseStorage(); | ||
$base.total += value; | ||
} |
Check warning
Code scanning / Slither
Divide before multiply Medium
- $.tempBorrowAmount = (flashAmounts[0] * maxLtv / 1e18) * priceCtoB / 1e18 - 2
function _withdrawAssets(uint value, address receiver) internal override returns (uint[] memory amountsOut) { | ||
LeverageLendingBaseStorage storage $ = _getLeverageLendingBaseStorage(); | ||
$.tempAction = CurrentAction.Withdraw; | ||
LeverageLendingAddresses memory v = LeverageLendingAddresses({ | ||
collateralAsset: $.collateralAsset, | ||
borrowAsset: $.borrowAsset, | ||
lendingVault: $.lendingVault, | ||
borrowingVault: $.borrowingVault | ||
}); | ||
amountsOut = new uint[](1); | ||
|
||
uint valueWas = StrategyLib.balance(v.collateralAsset) + _calcTotal(v); | ||
|
||
(uint maxLtv, uint maxLeverage,) = _getLtvData(v.lendingVault, $.targetLeveragePercent); | ||
|
||
(uint priceCtoB,) = _getPrices(ISilo(v.lendingVault).config(), v.lendingVault, $.borrowingVault); | ||
|
||
{ | ||
uint collateralAmountToWithdraw = value * maxLeverage / INTERNAL_PRECISION; | ||
$.tempCollateralAmount = collateralAmountToWithdraw; | ||
uint[] memory flashAmounts = new uint[](1); | ||
flashAmounts[0] = (collateralAmountToWithdraw * maxLtv / 1e18) * priceCtoB / 1e18; | ||
address[] memory flashAssets = new address[](1); | ||
flashAssets[0] = $.borrowAsset; | ||
IBVault($.flashLoanVault).flashLoan(address(this), flashAssets, flashAmounts, ""); | ||
} | ||
|
||
uint valueNow = StrategyLib.balance(v.collateralAsset) + _calcTotal(v); | ||
|
||
uint bal = StrategyLib.balance(v.collateralAsset); | ||
if (valueWas > valueNow) { | ||
//console.log('withdraw loss', valueWas - valueNow); | ||
amountsOut[0] = Math.min(value - (valueWas - valueNow), bal); | ||
} else { | ||
//console.log('withdraw profit', valueNow - valueWas); | ||
amountsOut[0] = Math.min(value + (valueNow - valueWas), bal); | ||
} | ||
|
||
IERC20(v.collateralAsset).safeTransfer(receiver, amountsOut[0]); | ||
|
||
StrategyBaseStorage storage $base = _getStrategyBaseStorage(); | ||
$base.total -= value; | ||
} |
Check warning
Code scanning / Slither
Divide before multiply Medium
- flashAmounts[0] = (collateralAmountToWithdraw * maxLtv / 1e18) * priceCtoB / 1e18
function _getLtvData( | ||
address lendingVault, | ||
uint targetLeveragePercent | ||
) internal view returns (uint maxLtv, uint maxLeverage, uint targetLeverage) { | ||
address configContract = ISilo(lendingVault).config(); | ||
ISiloConfig.ConfigData memory config = ISiloConfig(configContract).getConfig(lendingVault); | ||
maxLtv = config.maxLtv; | ||
maxLeverage = 1e18 * INTERNAL_PRECISION / (1e18 - maxLtv); | ||
targetLeverage = maxLeverage * targetLeveragePercent / INTERNAL_PRECISION; | ||
} |
Check warning
Code scanning / Slither
Divide before multiply Medium
- maxLeverage = 1e18 * INTERNAL_PRECISION / (1e18 - maxLtv)
- targetLeverage = maxLeverage * targetLeveragePercent / INTERNAL_PRECISION
No description provided.