adds initial vault valuation hsare implementation

This commit is contained in:
Vito
2026-03-17 20:23:03 +01:00
parent b45068b9dd
commit 57d31c3842
4 changed files with 43 additions and 20 deletions

View File

@@ -49,6 +49,7 @@ namespace math::v2 {
[[nodiscard]] Number
assetsToSharesDeposit(
Number const& assetTotal,
Number const& interestUnrealized,
Number const& shareTotal,
std::int32_t scale,
Number const& assets);
@@ -56,6 +57,7 @@ assetsToSharesDeposit(
[[nodiscard]] Number
sharesToAssetsDeposit(
Number const& assetTotal,
Number const& interestUnrealized,
Number const& shareTotal,
std::int32_t scale,
STAmount const& shares);
@@ -63,14 +65,15 @@ sharesToAssetsDeposit(
[[nodiscard]] Number
assetsToSharesWithdraw(
Number const& assetTotal,
Number const& interestUnrealized,
Number const& lossUnrealized,
Number const& shareTotal,
Number const& assets,
TruncateShares truncate = TruncateShares::no);
Number const& assets);
[[nodiscard]] Number
sharesToAssetsWithdraw(
Number const& assetTotal,
Number const& interestUnrealized,
Number const& lossUnrealized,
Number const& shareTotal,
STAmount const& shares);

View File

@@ -487,6 +487,7 @@ LEDGER_ENTRY(ltVAULT, 0x0084, Vault, vault, ({
{sfShareMPTID, soeREQUIRED},
{sfWithdrawalPolicy, soeREQUIRED},
{sfScale, soeDEFAULT},
{sfInterestUnrealized, soeDEFAULT},
// no SharesTotal ever (use MPTIssuance.sfOutstandingAmount)
// no PermissionedDomainID ever (use MPTIssuance.sfDomainID)
}))

View File

@@ -223,6 +223,7 @@ TYPED_SFIELD(sfPrincipalRequested, NUMBER, 14)
TYPED_SFIELD(sfTotalValueOutstanding, NUMBER, 15, SField::sMD_NeedsAsset | SField::sMD_Default)
TYPED_SFIELD(sfPeriodicPayment, NUMBER, 16)
TYPED_SFIELD(sfManagementFeeOutstanding, NUMBER, 17, SField::sMD_NeedsAsset | SField::sMD_Default)
TYPED_SFIELD(sfInterestUnrealized, NUMBER, 18, SField::sMD_NeedsAsset | SField::sMD_Default)
// int32
TYPED_SFIELD(sfLoanScale, INT32, 1)

View File

@@ -13,55 +13,61 @@ namespace math::v2 {
[[nodiscard]] Number
assetsToSharesDeposit(
Number const& assetTotal,
Number const& interestUnrealized,
Number const& shareTotal,
std::int32_t scale,
Number const& assets)
{
if (assetTotal == 0)
return Number(assets.mantissa(), assets.exponent() + scale).truncate();
return ((shareTotal * assets) / assetTotal).truncate();
auto const netAssetValue = assetTotal - interestUnrealized;
return ((shareTotal * assets) / netAssetValue).truncate();
}
[[nodiscard]] Number
sharesToAssetsDeposit(
Number const& assetTotal,
Number const& interestUnrealized,
Number const& shareTotal,
std::int32_t scale,
STAmount const& shares)
{
if (assetTotal == 0)
return Number(shares.mantissa(), shares.exponent() - scale);
return (assetTotal * shares) / shareTotal;
auto const netAssetValue = assetTotal - interestUnrealized;
return (netAssetValue * shares) / shareTotal;
}
[[nodiscard]] Number
assetsToSharesWithdraw(
Number const& assetTotal,
Number const& interestUnrealized,
Number const& lossUnrealized,
Number const& shareTotal,
Number const& assets,
TruncateShares truncate)
Number const& assets)
{
Number effectiveAssets = assetTotal - lossUnrealized;
if (effectiveAssets == 0)
Number netAssetValue = assetTotal - interestUnrealized - lossUnrealized;
if (netAssetValue == 0)
return Number(0);
Number result = (shareTotal * assets) / effectiveAssets;
if (truncate == TruncateShares::yes)
result = result.truncate();
return result;
return (shareTotal * assets) / netAssetValue;
}
[[nodiscard]] Number
sharesToAssetsWithdraw(
Number const& assetTotal,
Number const& interestUnrealized,
Number const& lossUnrealized,
Number const& shareTotal,
STAmount const& shares)
{
Number effectiveAssets = assetTotal - lossUnrealized;
if (effectiveAssets == 0)
Number netAssetValue = assetTotal - interestUnrealized - lossUnrealized;
if (netAssetValue == 0)
return Number(0);
return (effectiveAssets * shares) / shareTotal;
return (netAssetValue * shares) / shareTotal;
}
} // namespace math::v2
@@ -83,7 +89,11 @@ assetsToSharesDeposit(SLE::const_ref vault, SLE::const_ref issuance, STAmount co
STAmount shares{vault->at(sfShareMPTID)};
shares = math::v2::assetsToSharesDeposit(
vault->at(sfAssetsTotal), issuance->at(sfOutstandingAmount), vault->at(sfScale), assets);
vault->at(sfAssetsTotal),
vault->at(sfInterestUnrealized),
issuance->at(sfOutstandingAmount),
vault->at(sfScale),
assets);
return shares;
}
@@ -99,7 +109,11 @@ sharesToAssetsDeposit(SLE::const_ref vault, SLE::const_ref issuance, STAmount co
STAmount assets{vault->at(sfAsset)};
assets = math::v2::sharesToAssetsDeposit(
vault->at(sfAssetsTotal), issuance->at(sfOutstandingAmount), vault->at(sfScale), shares);
vault->at(sfAssetsTotal),
vault->at(sfInterestUnrealized),
issuance->at(sfOutstandingAmount),
vault->at(sfScale),
shares);
return assets;
}
@@ -119,12 +133,15 @@ assetsToSharesWithdraw(
return std::nullopt; // LCOV_EXCL_LINE
STAmount shares{vault->at(sfShareMPTID)};
shares = math::v2::assetsToSharesWithdraw(
Number result = math::v2::assetsToSharesWithdraw(
vault->at(sfAssetsTotal),
vault->at(sfInterestUnrealized),
vault->at(sfLossUnrealized),
issuance->at(sfOutstandingAmount),
assets,
truncate);
assets);
if (truncate == TruncateShares::yes)
result = result.truncate();
shares = result;
return shares;
}
@@ -142,6 +159,7 @@ sharesToAssetsWithdraw(SLE::const_ref vault, SLE::const_ref issuance, STAmount c
STAmount assets{vault->at(sfAsset)};
assets = math::v2::sharesToAssetsWithdraw(
vault->at(sfAssetsTotal),
vault->at(sfInterestUnrealized),
vault->at(sfLossUnrealized),
issuance->at(sfOutstandingAmount),
shares);