Smart Security Practices From The Best
What do Lido, Red Stone, YieldNest, and Braintrust have in common? They’ve developed effective methods for improving security without drastically increasing costs. Top-tier protocol […]
The primary outcome of this vulnerability is that the totalAssets variable will be inaccurately calculated, leading to theft of assets or potential losses for users due to undervalued totalAssets.
The processAccounting function is responsible for updating the amount of assets held in the vault. It iterates through all assets associated with the vault, retrieves their rates, and multiplies them by the vault’s balance. However, there are two key issues related to decimal handling in this computation.
function processAccounting() public virtual {
VaultStorage storage vaultStorage = _getVaultStorage();
uint256 totalBaseBalance = vaultStorage.countNativeAsset ? address(this).balance : 0;
AssetStorage storage assetStorage = _getAssetStorage();
address[] memory assetList = assetStorage.list;
uint256 assetListLength = assetList.length;
uint256 baseAssetUnit = 10 ** (assetStorage.assets[asset()].decimals);
for (uint256 i = 0; i < assetListLength; i++) {
uint256 balance = IERC20(assetList[i]).balanceOf(address(this));
if (balance == 0) continue;
uint256 rate = IProvider(provider()).getRate(assetList[i]);
totalBaseBalance += balance.mulDiv(rate, baseAssetUnit, Math.Rounding.Floor);
}
_getVaultStorage().totalAssets = totalBaseBalance;
emit ProcessAccounting(block.timestamp, totalBaseBalance);
}First, the calculation amount * rate uses the decimal places of the base asset rather than those of the iterated asset. If the decimal configuration of the base asset differs from that of the iterated asset, it can cause the totalAssets value to be incorrect by several orders of magnitude. This error could result in an inflated or deflated totalAssets, depending on whether the base asset has more or fewer decimal places than the iterated asset.
Second, the native asset is added to totalAssets without any adjustments for its decimal places. This can create additional inaccuracies if the base asset’s decimal configuration differs from that of the native asset, again leading to potential inflation or deflation of the totalAssets value.
An attacker could exploit these decimal-related vulnerabilities to improperly derive assets from the protocol by following these steps:
countNativeAsset set to true.totalAssets now amounts to 1,000,000 tokens.processAccounting function. The protocol computes the base asset amount as 1e12 (1,000,000 * 1e6) and the native amount figures at 1e13 (since 18 – 5 = 13), combining to yield a totalAssets of 11,000,000 tokens (1.1e13).totalAssets by 1e12 shares.HIGH – The primary outcome of this vulnerability is that the totalAssets variable will be inaccurately calculated, leading to theft of assets or potential losses for users due to undervalued totalAssets.
amount * rate.Meet Composable Security
Get throughly tested by the creators of Smart Contract Security Verification Standard
Let us help
Get throughly tested by the creators of Smart Contract Security Verification Standard