Tiny Licorice Loris
Medium
BridgeLogic.executeMintUnbacked()
fails to check if the reserve to be minted is paused.
function executeMintUnbacked(//@audit-issue A frozen, A paused reserve can still be supplied to and used as collateral.
mapping(address => DataTypes.ReserveData) storage reservesData,
mapping(uint256 => address) storage reservesList,
DataTypes.UserConfigurationMap storage userConfig,
address asset,
uint256 amount,
address onBehalfOf,
uint16 referralCode
) external {
DataTypes.ReserveData storage reserve = reservesData[asset];
DataTypes.ReserveCache memory reserveCache = reserve.cache();
reserve.updateState(reserveCache);
ValidationLogic.validateSupply(reserveCache, reserve, amount, onBehalfOf);
uint256 unbackedMintCap = reserveCache.reserveConfiguration.getUnbackedMintCap();
uint256 reserveDecimals = reserveCache.reserveConfiguration.getDecimals();
uint256 unbacked = reserve.unbacked += amount.toUint128();
require(
unbacked <= unbackedMintCap * (10 ** reserveDecimals),
Errors.UNBACKED_MINT_CAP_EXCEEDED
);
reserve.updateInterestRatesAndVirtualBalance(reserveCache, asset, 0, 0);
bool isFirstSupply = IAToken(reserveCache.aTokenAddress).mint(//@audit-ok `executeMintUnbacked()` can fail to `setUsingAsCollateral()` for first-time supply user. (A malicious user can prevent this by transferring a very minuscule amount to `onBehalfOf`)
msg.sender,
onBehalfOf,
amount,
reserveCache.nextLiquidityIndex
);
if (isFirstSupply) {
if (
ValidationLogic.validateAutomaticUseAsCollateral(
reservesData,
reservesList,
userConfig,
reserveCache.reserveConfiguration,
reserveCache.aTokenAddress
)
) {
userConfig.setUsingAsCollateral(reserve.id, true);
emit ReserveUsedAsCollateralEnabled(asset, onBehalfOf);
}
}
emit MintUnbacked(asset, msg.sender, onBehalfOf, amount, referralCode);
}
There's no check whatsoever in the logic of BridgeLogic.executeMintUnbacked()
to ascertain if the reserve to be minted is paused by admins.
So users can still mint unbacked for paused reserves and supply to them later via BridgeLogic.executeBackUnbacked()
This breaks the invariant where paused reserves shouldn't allow new supplies
/**
* @notice Pauses a reserve. A paused reserve does not allow any interaction (supply, borrow, repay,
* swap interest rate, liquidate, atoken transfers).
* @param asset The address of the underlying asset of the reserve
* @param paused True if pausing the reserve, false if unpausing
* @param gracePeriod Count of seconds after unpause during which liquidations will not be available
* - Only applicable whenever unpausing (`paused` as false)
* - Passing 0 means no grace period
* - Capped to maximum MAX_GRACE_PERIOD
*/
function setReservePause(address asset, bool paused, uint40 gracePeriod) external;
The logic of BridgeLogic.executeMintUnbacked()
fails to check if the asset reserve to be minted is paused.
Can happen anytime, all the time
- Admins pause an asset reserve via
Poolconfigurator.setReserveFreeze()
- User doesn't know, he uses
BridgeLogic.executeMintUnbacked()
for that asset reserve and if all conditions are met it even sets the asset reserve as collateral for him - User later supplies to the reserve later via
BridgeLogic.executeBackUnbacked()
A asset reserve paused by admins can still be used as collateral and supplied to by users.
This breaks the invariant where paused reserves shouldn't allow new supplies
/**
* @notice Pauses a reserve. A paused reserve does not allow any interaction (supply, borrow, repay,
* swap interest rate, liquidate, atoken transfers).
* @param asset The address of the underlying asset of the reserve
* @param paused True if pausing the reserve, false if unpausing
* @param gracePeriod Count of seconds after unpause during which liquidations will not be available
* - Only applicable whenever unpausing (`paused` as false)
* - Passing 0 means no grace period
* - Capped to maximum MAX_GRACE_PERIOD
*/
function setReservePause(address asset, bool paused, uint40 gracePeriod) external;
No response
check the flag of the asset reserve that BridgeLogic.executeMintUnbacked()
is to be used for and revert if it is paused