Skip to content

Commit

Permalink
Move distLossToTranches and distLossRecoveryToTranches from policy to…
Browse files Browse the repository at this point in the history
… pool
  • Loading branch information
bin-57blocks committed Dec 30, 2023
1 parent 4d3cbef commit 59d5f30
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 393 deletions.
43 changes: 0 additions & 43 deletions contracts/BaseTranchesPolicy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -64,49 +64,6 @@ abstract contract BaseTranchesPolicy is PoolConfigCache, ITranchesPolicy {
return (profitsForTrancheVault, profitsForFirstLossCover);
}

/// @inheritdoc ITranchesPolicy
function distLossToTranches(
uint256 loss,
uint96[2] memory assets
) external pure returns (uint96[2] memory updatedAssets, uint96[2] memory losses) {
uint256 juniorTotalAssets = assets[JUNIOR_TRANCHE];
// Distribute losses to junior tranche up to the total junior asset
losses[JUNIOR_TRANCHE] = uint96(juniorTotalAssets >= loss ? loss : juniorTotalAssets);
losses[SENIOR_TRANCHE] = uint96(loss - losses[JUNIOR_TRANCHE]);
updatedAssets[JUNIOR_TRANCHE] = uint96(assets[JUNIOR_TRANCHE] - losses[JUNIOR_TRANCHE]);
updatedAssets[SENIOR_TRANCHE] = uint96(assets[SENIOR_TRANCHE] - losses[SENIOR_TRANCHE]);

return (updatedAssets, losses);
}

/// @inheritdoc ITranchesPolicy
function distLossRecoveryToTranches(
uint256 lossRecovery,
uint96[2] memory assets,
uint96[2] memory losses
) external pure returns (uint256 remainingLossRecovery, uint96[2] memory, uint96[2] memory) {
uint96 seniorLoss = losses[SENIOR_TRANCHE];
// Allocates recovery to senior first, up to the total senior losses
uint256 seniorLossRecovery = lossRecovery >= seniorLoss ? seniorLoss : lossRecovery;
if (seniorLossRecovery > 0) {
assets[SENIOR_TRANCHE] += uint96(seniorLossRecovery);
losses[SENIOR_TRANCHE] -= uint96(seniorLossRecovery);
}

remainingLossRecovery = lossRecovery - seniorLossRecovery;
if (remainingLossRecovery > 0) {
uint96 juniorLoss = losses[JUNIOR_TRANCHE];
uint256 juniorLossRecovery = remainingLossRecovery >= juniorLoss
? juniorLoss
: remainingLossRecovery;
assets[JUNIOR_TRANCHE] += uint96(juniorLossRecovery);
losses[JUNIOR_TRANCHE] -= uint96(juniorLossRecovery);
remainingLossRecovery = remainingLossRecovery - juniorLossRecovery;
}

return (remainingLossRecovery, assets, losses);
}

/// @inheritdoc ITranchesPolicy
function refreshYieldTracker(uint96[2] memory assets) public virtual {
// Empty function for RiskAdjustedTranchePolicy
Expand Down
116 changes: 73 additions & 43 deletions contracts/Pool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -274,30 +274,39 @@ contract Pool is PoolConfigCache, IPool {

if (loss > 0) {
// If there are losses remaining, let the junior and senior tranches cover the losses.
TranchesAssets memory assets = tranchesAssets;
(uint96[2] memory newAssets, uint96[2] memory lossesDelta) = tranchesPolicy
.distLossToTranches(
loss,
[assets.seniorTotalAssets, assets.juniorTotalAssets]
);
_updateTranchesAssets(newAssets);

TranchesLosses memory losses = tranchesLosses;
losses.seniorLoss += lossesDelta[SENIOR_TRANCHE];
losses.juniorLoss += lossesDelta[JUNIOR_TRANCHE];
tranchesLosses = losses;

emit LossDistributed(
loss,
newAssets[SENIOR_TRANCHE],
newAssets[JUNIOR_TRANCHE],
losses.seniorLoss,
losses.juniorLoss
);
_distLossToTranches(loss);
}
}
}

/**
* @notice Distributes loss to tranches
* @param loss the loss amount
*/
function _distLossToTranches(uint256 loss) internal {
TranchesAssets memory assets = tranchesAssets;
uint256 juniorTotalAssets = assets.juniorTotalAssets;
// Distribute losses to junior tranche up to the total junior asset
uint256 juniorLoss = juniorTotalAssets >= loss ? loss : juniorTotalAssets;
uint256 seniorLoss = loss - juniorLoss;

assets.seniorTotalAssets -= uint96(seniorLoss);
assets.juniorTotalAssets -= uint96(juniorLoss);
_updateTranchesAssets([assets.seniorTotalAssets, assets.juniorTotalAssets]);
TranchesLosses memory losses = tranchesLosses;
losses.seniorLoss += uint96(seniorLoss);
losses.juniorLoss += uint96(juniorLoss);
tranchesLosses = losses;

emit LossDistributed(
loss,
assets.seniorTotalAssets,
assets.juniorTotalAssets,
losses.seniorLoss,
losses.juniorLoss
);
}

/**
* @notice Utility function that distributes loss recovery to different tranches and
* First Loss Covers (FLCs). The distribution sequence is: senior tranche, junior tranche,
Expand All @@ -307,29 +316,7 @@ contract Pool is PoolConfigCache, IPool {
*/
function _distributeLossRecovery(uint256 lossRecovery) internal {
if (lossRecovery > 0) {
TranchesAssets memory assets = tranchesAssets;
TranchesLosses memory losses = tranchesLosses;
(
uint256 remainingLossRecovery,
uint96[2] memory newAssets,
uint96[2] memory newLosses
) = tranchesPolicy.distLossRecoveryToTranches(
lossRecovery,
[assets.seniorTotalAssets, assets.juniorTotalAssets],
[losses.seniorLoss, losses.juniorLoss]
);
_updateTranchesAssets(newAssets);
tranchesLosses = TranchesLosses({
seniorLoss: newLosses[SENIOR_TRANCHE],
juniorLoss: newLosses[JUNIOR_TRANCHE]
});
emit LossRecoveryDistributed(
lossRecovery - remainingLossRecovery,
newAssets[SENIOR_TRANCHE],
newAssets[JUNIOR_TRANCHE],
newLosses[SENIOR_TRANCHE],
newLosses[JUNIOR_TRANCHE]
);
uint256 remainingLossRecovery = _distLossRecoveryToTranches(lossRecovery);

// Distributes the remainder to First Loss Covers.
uint256 numFirstLossCovers = _firstLossCovers.length;
Expand All @@ -340,6 +327,49 @@ contract Pool is PoolConfigCache, IPool {
}
}

/**
* @notice Distributes loss recovery to tranches
* @param lossRecovery the loss recovery amount
* @return remainingLossRecovery the remaining loss recovery after distributing among tranches
*/
function _distLossRecoveryToTranches(
uint256 lossRecovery
) internal returns (uint256 remainingLossRecovery) {
TranchesAssets memory assets = tranchesAssets;
TranchesLosses memory losses = tranchesLosses;
uint96 seniorLoss = losses.seniorLoss;
// Allocates recovery to senior first, up to the total senior losses
uint256 seniorLossRecovery = lossRecovery >= seniorLoss ? seniorLoss : lossRecovery;
if (seniorLossRecovery > 0) {
assets.seniorTotalAssets += uint96(seniorLossRecovery);
losses.seniorLoss -= uint96(seniorLossRecovery);
}

remainingLossRecovery = lossRecovery - seniorLossRecovery;
if (remainingLossRecovery > 0) {
uint96 juniorLoss = losses.juniorLoss;
uint256 juniorLossRecovery = remainingLossRecovery >= juniorLoss
? juniorLoss
: remainingLossRecovery;
assets.juniorTotalAssets += uint96(juniorLossRecovery);
losses.juniorLoss -= uint96(juniorLossRecovery);
remainingLossRecovery = remainingLossRecovery - juniorLossRecovery;
}

_updateTranchesAssets([assets.seniorTotalAssets, assets.juniorTotalAssets]);
tranchesLosses = losses;

emit LossRecoveryDistributed(
lossRecovery - remainingLossRecovery,
assets.seniorTotalAssets,
assets.juniorTotalAssets,
losses.seniorLoss,
losses.juniorLoss
);

return remainingLossRecovery;
}

/**
* @notice Gets the total asset of a tranche
* @param index the tranche index.
Expand Down
36 changes: 0 additions & 36 deletions contracts/interfaces/ITranchesPolicy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,6 @@ pragma solidity ^0.8.0;
*/

interface ITranchesPolicy {
/**
* @notice Distributes loss to tranches
* @dev Passing asset value for the tranches as a parameter to make the function stateless
* @param loss the loss amount
* @param assets assets for each tranche, index 0 for senior, 1 for junior
* @return updatedAssets updated total assets for each tranche
* @return losses losses for each tranche
*/
function distLossToTranches(
uint256 loss,
uint96[2] memory assets
) external pure returns (uint96[2] memory updatedAssets, uint96[2] memory losses);

/**
* @notice Distributes loss recovery to tranches
* @dev Passing asset value for the tranches as a parameter to make the function stateless
* @param lossRecovery the loss recovery amount
* @param assets assets for each tranche, index 0 for senior, 1 for junior
* @param losses losses for each tranche, index 0 for senior, 1 for junior
* @return remainingLossRecovery the remaining loss recovery after distributing among tranches
* @return newAssets updated total assets for each tranche, index 0 for senior, 1 for junior
* @return newLosses updated total losses for each tranche, index 0 for senior, 1 for junior
*/
function distLossRecoveryToTranches(
uint256 lossRecovery,
uint96[2] memory assets,
uint96[2] memory losses
)
external
pure
returns (
uint256 remainingLossRecovery,
uint96[2] memory newAssets,
uint96[2] memory newLosses
);

/**
* @notice Distributes profit to tranches
* @dev Passing asset value for the tranches as a parameter to make the function stateless
Expand Down
Loading

0 comments on commit 59d5f30

Please sign in to comment.