Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: medium
Valid

The variables for curve calculation to identify either discount or premium were not set, will always revert on modulo zero,

Summary

While swapping usdToken for vaults assets , we need to find the discount or premium which we will apply on assets out , To Do so we have implemented curve formula which required pdCurveXMinX18, pdCurveXMaxX18, pdCurveYMinX18 , pdCurveYMaxX18 and pdCurveZX18 However there is no function which can allow the owner of vault to set these variables. So It will always revert.

Vulnerability Details

The UsdTokenSwapConfig stores following variables:

/src/market-making/leaves/UsdTokenSwapConfig.sol:61
61: struct Data {
62: uint128 baseFeeUsd; // 1 USD
63: uint128 swapSettlementFeeBps; // 0.3 %
64: uint128 maxExecutionTime;
65: uint128 pdCurveYMin;
66: uint128 pdCurveYMax;
67: uint128 pdCurveXMin;
68: uint128 pdCurveXMax;
69: uint128 pdCurveZ;
70: mapping(address engine => uint256 availableUsdc) usdcAvailableForEngine;
71: mapping(address => uint128) swapRequestIdCounter;
72: mapping(address => mapping(uint128 => SwapRequest)) swapRequests;
73: }
74:
75: /// @notice Loads the {UsdTokenSwapConfig}.

the code have update funciton which will update following variables:

62: uint128 baseFeeUsd; // 1 USD
63: uint128 swapSettlementFeeBps; // 0.3 %
64: uint128 maxExecutionTime

There is no funciton which will help us to update these variables:

65: uint128 pdCurveYMin;
66: uint128 pdCurveYMax;
67: uint128 pdCurveXMin;
68: uint128 pdCurveXMax;
69: uint128 pdCurveZ;

Due to no setter all these variable will be set to 0. and no premium or discount calculation will be successful if (vaultDebtTvlRatioAbs.lte(pdCurveXMinX18)) check fail.
##POC

function test_it_Will_revert( // @audit POC
)
external
whenCallerIsKeeper
whenRequestWasNotYetProcessed
whenSwapRequestNotExpired
{
uint256 vaultId = 100;
uint256 marketId = 100;
uint256 vaultAssetsBalance = 5000e22;
uint256 swapAmount = 1000e18;
uint128 vaultDebtAbsUsd = uint128(2.33e30);
bool useCredit= false;
// working data
TestFuzz_WhenSlippageCheckPassesAndThePremiumOrDiscountIsNotZero_Context memory ctx;
ctx.fuzzVaultConfig = getFuzzVaultConfig(vaultId);
ctx.oneAsset = 10 ** ctx.fuzzVaultConfig.decimals;
changePrank({ msgSender: users.owner.account });
marketMakingEngine.configureUsdTokenSwapConfig(1, 30, type(uint96).max);
marketMakingEngine.workaround_setVaultDebt(uint128(ctx.fuzzVaultConfig.vaultId),-int128(vaultDebtAbsUsd));
marketMakingEngine.workaround_setVaultDepositedUsdc(uint128(ctx.fuzzVaultConfig.vaultId),0);
changePrank({ msgSender: users.naruto.account });
deal({
token: address(ctx.fuzzVaultConfig.asset),
to: ctx.fuzzVaultConfig.indexToken,
give: vaultAssetsBalance
});
swapAmount = vaultAssetsBalance;
deal({ token: address(usdToken), to: users.naruto.account, give: swapAmount });
ctx.fuzzPerpMarketCreditConfig = getFuzzPerpMarketCreditConfig(marketId);
ctx.engine = IMockEngine(perpMarketsCreditConfig[ctx.fuzzPerpMarketCreditConfig.marketId].engine);
ctx.minAmountOut = 0;
UD60x18 priceUsdX18 = IPriceAdapter(vaultsConfig[ctx.fuzzVaultConfig.vaultId].priceAdapter).getPrice();
ctx.priceData = getMockedSignedReport(ctx.fuzzVaultConfig.streamId, priceUsdX18.intoUint256());
ctx.usdTokenSwapKeeper = usdTokenSwapKeepers[ctx.fuzzVaultConfig.asset];
vm.expectRevert();
UD60x18 negativeDebtAmountOut =
marketMakingEngine.getAmountOfAssetOut(ctx.fuzzVaultConfig.vaultId, ud60x18(swapAmount), priceUsdX18);
}

Impact

The Swapping will always fail if discount or premium must be applied.

Tools Used

Manual Review

Recommendations

Add a Setter function where the owner can set these variables:

Updates

Lead Judging Commences

inallhonesty Lead Judge 3 months ago
Submission Judgement Published
Validated
Assigned finding tags:

PremiumDiscountFactor feature cannot be properly configured / used

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.