Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Runtime fv #30

Merged
merged 33 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
2efc4da
delete sweep assets and integrate token transfer into redeem repo tokens
aazhou1 Sep 5, 2024
1e6e4d2
refactor calculations to use utils
aazhou1 Sep 10, 2024
9dc10e4
revert repo token holding value
aazhou1 Sep 10, 2024
a127c5c
refactor a new oracle wallet in test setup
aazhou1 Sep 10, 2024
916b05d
miscellaneous audit fixes
aazhou1 Sep 10, 2024
eca56c4
cache total asset value
aazhou1 Sep 10, 2024
9316f4d
docs error
aazhou1 Sep 10, 2024
6c266ac
require total asset value > 0 in submitAuctionOffer
aazhou1 Sep 10, 2024
90298bf
align comments
aazhou1 Sep 10, 2024
ce3758d
sweep if funds freed
aazhou1 Sep 10, 2024
0cc51aa
remove extra space
aazhou1 Sep 10, 2024
d92fc3a
Merge pull request #22 from term-finance/misc-fixes
aazhou1 Sep 10, 2024
e84b147
Merge branch 'runtime-fv' into redeem-covers-sweep
aazhou1 Sep 10, 2024
5dbc3cb
Merge pull request #17 from term-finance/redeem-covers-sweep
aazhou1 Sep 10, 2024
453811d
Merge branch 'runtime-fv' into cache-total-asset-value
aazhou1 Sep 10, 2024
9aeb24f
Merge pull request #23 from term-finance/cache-total-asset-value
aazhou1 Sep 10, 2024
d9b78cf
Merge branch 'runtime-fv' into sweep-if-funds-freed
aazhou1 Sep 10, 2024
3576e61
Merge pull request #24 from term-finance/sweep-if-funds-freed
aazhou1 Sep 10, 2024
dc817e4
Merge branch 'runtime-fv' into refactor
aazhou1 Sep 10, 2024
f593f02
Merge pull request #21 from term-finance/refactor
aazhou1 Sep 10, 2024
a6410f2
fixes getNormalized repo token amount to only apply redemption haircu…
aazhou1 Sep 10, 2024
a85d286
fixing unit tests
0xddong Sep 11, 2024
adc5dae
Merge pull request #25 from term-finance/fix-normalized
aazhou1 Sep 11, 2024
ea792f1
get rid of unneccessary looping for present value of single token
aazhou1 Sep 12, 2024
706bef2
remove memory load
aazhou1 Sep 12, 2024
3c59187
fix test name
aazhou1 Sep 12, 2024
7ab2aaa
increment linked list counter
aazhou1 Sep 12, 2024
6d1ea56
load offer into memory on first insert in auction list
aazhou1 Sep 12, 2024
a23c0d9
cleanup
aazhou1 Sep 12, 2024
ddeaf44
Merge pull request #28 from term-finance/unneccessary-loop
aazhou1 Sep 12, 2024
bd57261
Merge branch 'runtime-fv' into no-memory-load
aazhou1 Sep 12, 2024
c36a2be
fix mispelling in docs
aazhou1 Sep 12, 2024
960a02e
Merge pull request #29 from term-finance/no-memory-load
aazhou1 Sep 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 14 additions & 34 deletions src/RepoTokenList.sol
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ library RepoTokenList {
/**
* @notice This function calculates the cumulative weighted time to maturity and cumulative amount of all repoTokens in the list.
* @param listData The list data
* @param discountRateAdapter The discount rate adapter
* @param repoToken The address of the repoToken (optional)
* @param repoTokenAmount The amount of the repoToken (optional)
* @param purchaseTokenPrecision The precision of the purchase token
Expand All @@ -127,6 +128,7 @@ library RepoTokenList {
*/
function getCumulativeRepoTokenData(
RepoTokenListData storage listData,
ITermDiscountRateAdapter discountRateAdapter,
address repoToken,
uint256 repoTokenAmount,
uint256 purchaseTokenPrecision
Expand All @@ -148,12 +150,10 @@ library RepoTokenList {
}

// Convert the repo token balance to base asset precision
uint256 redemptionValue = ITermRepoToken(current).redemptionValue();
uint256 repoTokenPrecision = 10**ERC20(current).decimals();

uint256 repoTokenBalanceInBaseAssetPrecision =
(redemptionValue * repoTokenBalance * purchaseTokenPrecision) /
(repoTokenPrecision * RepoTokenUtils.RATE_PRECISION);
RepoTokenUtils.getNormalizedRepoTokenAmount(
current, repoTokenBalance, purchaseTokenPrecision, discountRateAdapter.repoRedemptionHaircut(current)
);

// Calculate the weighted time to maturity
uint256 weightedTimeToMaturity = getRepoTokenWeightedTimeToMaturity(
Expand All @@ -173,45 +173,31 @@ library RepoTokenList {
/**
* @notice Get the present value of repoTokens
* @param listData The list data
* @param discountRateAdapter The discount rate adapter
* @param purchaseTokenPrecision The precision of the purchase token
* @param repoTokenToMatch The address of the repoToken to match (optional)
* @return totalPresentValue The total present value of the repoTokens
* @dev If the `repoTokenToMatch` parameter is provided (non-zero address), the function will filter
* the calculations to include only the specified repoToken. If `repoTokenToMatch` is not provided
* (zero address), it will aggregate the present value of all repoTokens in the list.
*
* Example usage:
* - To get the present value of all repoTokens: call with `repoTokenToMatch` set to `address(0)`.
* - To get the present value of a specific repoToken: call with `repoTokenToMatch` set to the address of the desired repoToken.
* @dev Aggregates the present value of all repoTokens in the list.
*/
function getPresentValue(
RepoTokenListData storage listData,
uint256 purchaseTokenPrecision,
address repoTokenToMatch
ITermDiscountRateAdapter discountRateAdapter,
uint256 purchaseTokenPrecision
) internal view returns (uint256 totalPresentValue) {
// If the list is empty, return 0
if (listData.head == NULL_NODE) return 0;

address current = listData.head;
while (current != NULL_NODE) {
// Filter by a specific repoToken, address(0) bypasses this filter
if (repoTokenToMatch != address(0) && current != repoTokenToMatch) {
// Not a match, do not add to totalPresentValue
// Move to the next token in the list
current = _getNext(listData, current);
continue;
}

uint256 currentMaturity = getRepoTokenMaturity(current);
uint256 repoTokenBalance = ITermRepoToken(current).balanceOf(address(this));
uint256 repoTokenPrecision = 10**ERC20(current).decimals();
uint256 discountRate = listData.discountRates[current];
uint256 discountRate = discountRateAdapter.getDiscountRate(current);

// Convert repo token balance to base asset precision
// (ratePrecision * repoPrecision * purchasePrecision) / (repoPrecision * ratePrecision) = purchasePrecision
uint256 repoTokenBalanceInBaseAssetPrecision =
(ITermRepoToken(current).redemptionValue() * repoTokenBalance * purchaseTokenPrecision) /
(repoTokenPrecision * RepoTokenUtils.RATE_PRECISION);
RepoTokenUtils.getNormalizedRepoTokenAmount(
current, repoTokenBalance, purchaseTokenPrecision, discountRateAdapter.repoRedemptionHaircut(current)
);

// Calculate present value based on maturity
if (currentMaturity > block.timestamp) {
Expand All @@ -222,12 +208,6 @@ library RepoTokenList {
totalPresentValue += repoTokenBalanceInBaseAssetPrecision;
}

// Filter by a specific repo token, address(0) bypasses this condition
if (repoTokenToMatch != address(0) && current == repoTokenToMatch) {
// Found a match, terminate early
break;
}

// Move to the next token in the list
current = _getNext(listData, current);
}
Expand Down Expand Up @@ -324,7 +304,7 @@ library RepoTokenList {
(redemptionTimestamp, purchaseToken, , collateralManager) = repoToken.config();

// Validate purchase token
if (purchaseToken != address(asset)) {
if (purchaseToken != asset) {
revert InvalidRepoToken(address(repoToken));
}

Expand Down
44 changes: 7 additions & 37 deletions src/RepoTokenUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,40 +12,6 @@ library RepoTokenUtils {
uint256 public constant THREESIXTY_DAYCOUNT_SECONDS = 360 days;
uint256 public constant RATE_PRECISION = 1e18;

/*//////////////////////////////////////////////////////////////
PURE FUNCTIONS
//////////////////////////////////////////////////////////////*/

/**
* @notice Convert repoToken amount to purchase token precision
* @param repoTokenPrecision The precision of the repoToken
* @param purchaseTokenPrecision The precision of the purchase token
* @param purchaseTokenAmountInRepoPrecision The amount of purchase token in repoToken precision
* @return The amount in purchase token precision
*/
function repoToPurchasePrecision(
uint256 repoTokenPrecision,
uint256 purchaseTokenPrecision,
uint256 purchaseTokenAmountInRepoPrecision
) internal pure returns (uint256) {
return (purchaseTokenAmountInRepoPrecision * purchaseTokenPrecision) / repoTokenPrecision;
}

/**
* @notice Convert purchase token amount to repoToken precision
* @param repoTokenPrecision The precision of the repoToken
* @param purchaseTokenPrecision The precision of the purchase token
* @param repoTokenAmount The amount of repoToken
* @return The amount in repoToken precision
*/
function purchaseToRepoPrecision(
uint256 repoTokenPrecision,
uint256 purchaseTokenPrecision,
uint256 repoTokenAmount
) internal pure returns (uint256) {
return (repoTokenAmount * repoTokenPrecision) / purchaseTokenPrecision;
}

/*//////////////////////////////////////////////////////////////
VIEW FUNCTIONS
//////////////////////////////////////////////////////////////*/
Expand Down Expand Up @@ -78,17 +44,21 @@ library RepoTokenUtils {
* @param repoToken The address of the repoToken
* @param repoTokenAmount The amount of the repoToken
* @param purchaseTokenPrecision The precision of the purchase token
* @param repoRedemptionHaircut The haircut to be applied to the repoToken for bad debt
* @return repoTokenAmountInBaseAssetPrecision The normalized amount of the repoToken in base asset precision
*/
function getNormalizedRepoTokenAmount(
address repoToken,
uint256 repoTokenAmount,
uint256 purchaseTokenPrecision
uint256 purchaseTokenPrecision,
uint256 repoRedemptionHaircut
) internal view returns (uint256 repoTokenAmountInBaseAssetPrecision) {
uint256 repoTokenPrecision = 10**ERC20(repoToken).decimals();
uint256 redemptionValue = ITermRepoToken(repoToken).redemptionValue();
repoTokenAmountInBaseAssetPrecision =
(redemptionValue * repoTokenAmount * purchaseTokenPrecision) /
(repoTokenPrecision * RepoTokenUtils.RATE_PRECISION);
repoRedemptionHaircut != 0 ?
(redemptionValue * repoRedemptionHaircut * repoTokenAmount * purchaseTokenPrecision) /
(repoTokenPrecision * RATE_PRECISION * 1e18)
: (redemptionValue * repoTokenAmount * purchaseTokenPrecision) / (repoTokenPrecision * RATE_PRECISION);
}
}
Loading
Loading