Instead of the borrow token's total supply, the Multicall.sol uses address(this) balances to validate the borrow token's supply cap, causing borrow tokens to be minted above the supply cap.
Proof of Concept
During a multicall, the size protocol contract verifies that the resulting borrow token supply is less than or equal than to the decrease in the debt token supply.
function validateBorrowATokenIncreaseLteDebtTokenDecrease(
State storage state,
>> uint256 borrowATokenSupplyBefore,
uint256 debtTokenSupplyBefore,
>> uint256 borrowATokenSupplyAfter,
uint256 debtTokenSupplyAfter
) external view {
// If the supply is above the cap
if (borrowATokenSupplyAfter > state.riskConfig.borrowATokenCap) {
uint256 borrowATokenSupplyIncrease = borrowATokenSupplyAfter > borrowATokenSupplyBefore
? borrowATokenSupplyAfter - borrowATokenSupplyBefore
: 0;
uint256 debtATokenSupplyDecrease =
debtTokenSupplyBefore > debtTokenSupplyAfter ? debtTokenSupplyBefore - debtTokenSupplyAfter : 0;
// and the supply increase is greater than the debt reduction
if (borrowATokenSupplyIncrease > debtATokenSupplyDecrease) {
// revert
revert Errors.BORROW_ATOKEN_INCREASE_EXCEEDS_DEBT_TOKEN_DECREASE(
borrowATokenSupplyIncrease, debtATokenSupplyDecrease
);
}
// otherwise, it means the debt reduction was greater than the inflow of cash: do not revert
}
// otherwise, the supply is below the cap: do not revert
}
borrowATokenSupplyBefore and borrowATokenSupplyAfter variables are received from the Multicall.sol library:
The problem here is that contract balances are used instead of totalSupply. This will result in an incorrect assessment of the increase in the total supply of borrow tokens relative to the decrease in the supply of debt tokens.
Note how borrow token supply cap is validated in the validateBorrowATokenCap function.
function validateBorrowATokenCap(State storage state) external view {
if (state.data.borrowAToken.totalSupply() > state.riskConfig.borrowATokenCap) {
revert Errors.BORROW_ATOKEN_CAP_EXCEEDED(
state.riskConfig.borrowATokenCap, state.data.borrowAToken.totalSupply()
);
}
}
Lines of code
https://github.com/code-423n4/2024-06-size/blob/main/src/libraries/Multicall.sol#L29 https://github.com/code-423n4/2024-06-size/blob/main/src/libraries/Multicall.sol#L29
Vulnerability details
Impact
Instead of the borrow token's total supply, the
Multicall.sol
usesaddress(this)
balances to validate the borrow token's supply cap, causing borrow tokens to be minted above the supply cap.Proof of Concept
During a multicall, the size protocol contract verifies that the resulting borrow token supply is less than or equal than to the decrease in the debt token supply.
borrowATokenSupplyBefore
andborrowATokenSupplyAfter
variables are received from theMulticall.sol
library:The problem here is that contract balances are used instead of
totalSupply
. This will result in an incorrect assessment of the increase in the total supply of borrow tokens relative to the decrease in the supply of debt tokens.Note how borrow token supply cap is validated in the
validateBorrowATokenCap
function.Tools Used
Manual review
Recommended Mitigation Steps
Assessed type
Invalid Validation