Breezy Basil Toad
Medium
the leverage function increases the leverage of a given collateral position by retrieving borrow tokens and trading it for collateral token and deposits collateral token however when executing the trade the function does not account for the protocol fee when calculating the minNotionalReceiveQuantity
the lever function calls
function lever(
ISetToken _setToken,
uint256 _borrowQuantityUnits,
uint256 _minReceiveQuantityUnits,
string memory _tradeAdapterName,
bytes memory _tradeData
)
external
nonReentrant
onlyManagerAndValidSet(_setToken)
{
MarketParams memory setMarketParams = marketParams[_setToken];
require(setMarketParams.collateralToken != address(0), "Collateral not set");
// For levering up, send quantity is derived from borrow asset and receive quantity is derived from
// collateral asset
ActionInfo memory leverInfo = _createAndValidateActionInfo(
_setToken,
IERC20(setMarketParams.loanToken),
IERC20(setMarketParams.collateralToken),
_borrowQuantityUnits,
_minReceiveQuantityUnits,
_tradeAdapterName,
true
);
_borrow(leverInfo.setToken, setMarketParams, leverInfo.notionalSendQuantity)
uint256 postTradeReceiveQuantity = _executeTrade(leverInfo, IERC20(setMarketParams.loanToken), IERC20(setMarketParams.collateralToken), _tradeData); ////@audit
uint256 protocolFee = _accrueProtocolFee(_setToken, IERC20(setMarketParams.collateralToken), postTradeReceiveQuantity);
uint256 postTradeCollateralQuantity = postTradeReceiveQuantity.sub(protocolFee);
_deposit(leverInfo.setToken, setMarketParams, postTradeCollateralQuantity);
_sync(leverInfo.setToken);
function _executeTrade(
ActionInfo memory _actionInfo,
IERC20 _sendToken,
IERC20 _receiveToken,
bytes memory _data
)
internal
returns (uint256)
{
ISetToken setToken = _actionInfo.setToken;
uint256 notionalSendQuantity = _actionInfo.notionalSendQuantity;
setToken.invokeApprove(
address(_sendToken),
_actionInfo.exchangeAdapter.getSpender(),
notionalSendQuantity
);
(
address targetExchange,
uint256 callValue,
bytes memory methodData
) = _actionInfo.exchangeAdapter.getTradeCalldata(
address(_sendToken),
address(_receiveToken),
address(setToken),
notionalSendQuantity,
_actionInfo.minNotionalReceiveQuantity,
_data
);
setToken.invoke(targetExchange, callValue, methodData);
uint256 receiveTokenQuantity = _receiveToken.balanceOf(address(setToken)).sub(_actionInfo.preTradeReceiveTokenBalance);
require(
receiveTokenQuantity >= _actionInfo.minNotionalReceiveQuantity,
"Slippage too high" ////@audit
);
return receiveTokenQuantity;
as we can see here if the receivequantity is less than minNotionalReceiveQuantity the function reverts this fails to account for the protocol fee when executing the trade however it accounts for the fee after the trade is executed
No response
No response
No response
temporary dos
No response
account for the protocol fee when executing the trade