fix: floating point representation errors in vault (#5997)

This change fixes floating point errors in conversion of shares to assets and other way, used in `VaultDeposit`, `VaultWithdraw` and `VaultClawback`. In the floating point calculations the division introduces a larger error than multiplication. If we do division first, then the error introduced will be increased by the multiplication that follows, which is therefore the wrong order to perform these two operations. This change flips the order of arithmetic operations, which minimizes the error.
This commit is contained in:
Bronek Kozicki
2025-11-11 19:39:09 +00:00
parent 865557024e
commit 4135d56aa0
2 changed files with 86 additions and 5 deletions

View File

@@ -2904,7 +2904,7 @@ assetsToSharesDeposit(
.truncate()};
Number const shareTotal = issuance->at(sfOutstandingAmount);
shares = (shareTotal * (assets / assetTotal)).truncate();
shares = ((shareTotal * assets) / assetTotal).truncate();
return shares;
}
@@ -2933,7 +2933,7 @@ sharesToAssetsDeposit(
false};
Number const shareTotal = issuance->at(sfOutstandingAmount);
assets = assetTotal * (shares / shareTotal);
assets = (assetTotal * shares) / shareTotal;
return assets;
}
@@ -2959,7 +2959,7 @@ assetsToSharesWithdraw(
if (assetTotal == 0)
return shares;
Number const shareTotal = issuance->at(sfOutstandingAmount);
Number result = shareTotal * (assets / assetTotal);
Number result = (shareTotal * assets) / assetTotal;
if (truncate == TruncateShares::yes)
result = result.truncate();
shares = result;
@@ -2987,7 +2987,7 @@ sharesToAssetsWithdraw(
if (assetTotal == 0)
return assets;
Number const shareTotal = issuance->at(sfOutstandingAmount);
assets = assetTotal * (shares / shareTotal);
assets = (assetTotal * shares) / shareTotal;
return assets;
}