From 978885552519f12ff14caeb5623ca4133fb46b22 Mon Sep 17 00:00:00 2001 From: aalavandhan1984 <6264334+aalavandhan@users.noreply.github.com> Date: Mon, 27 Feb 2023 14:24:30 -0500 Subject: [PATCH] code review updates --- .../contracts/_utils/BondHelpers.sol | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/spot-contracts/contracts/_utils/BondHelpers.sol b/spot-contracts/contracts/_utils/BondHelpers.sol index c71769d6..fa4b1fb6 100644 --- a/spot-contracts/contracts/_utils/BondHelpers.sol +++ b/spot-contracts/contracts/_utils/BondHelpers.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.18; import { SafeCastUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol"; +import { MathUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol"; import { IERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import { IBondController } from "../_interfaces/buttonwood/IBondController.sol"; @@ -191,8 +192,8 @@ library BondHelpers { return (td, collateralBalances, trancheSupplies); } - /// @notice Given a bond and a user address computes the tranche amounts proportional to the tranche ratios, - // that can be redeemed for the collateral before maturity. + /// @notice For a given bond and user address, computes the maximum number of each of the bond's tranches + /// the user is able to redeem before the bond's maturity. These tranche amounts necessarily match the bond's tranche ratios. /// @param b The address of the bond contract. /// @param u The address to check balance for. /// @return The tranche data and an array of tranche token balances. @@ -204,18 +205,28 @@ library BondHelpers { TrancheData memory td = getTrancheData(b); uint256[] memory redeemableAmts = new uint256[](td.trancheCount); - // We calculate the minimum value of {trancheBal/trancheRatio} across tranches - uint256 min = type(uint256).max; + // Calculate how many underlying assets could be redeemed from each tranche balance, + // assuming other tranches are not an issue, and record the smallest amount. + uint256 minUnderlyingOut = type(uint256).max; uint8 i; - for (i = 0; i < td.trancheCount && min != 0; i++) { - uint256 d = (td.tranches[i].balanceOf(u) * TRANCHE_RATIO_GRANULARITY) / td.trancheRatios[i]; - if (d < min) { - min = d; + for (i = 0; i < td.trancheCount; i++) { + uint256 d = MathUpgradeable.mulDiv( + td.tranches[i].balanceOf(u), + TRANCHE_RATIO_GRANULARITY, + td.trancheRatios[i] + ); + if (d < minUnderlyingOut) { + minUnderlyingOut = d; + } + + // if one of the balances is zero, we return + if (minUnderlyingOut == 0) { + return (td, redeemableAmts); } } for (i = 0; i < td.trancheCount; i++) { - redeemableAmts[i] = (td.trancheRatios[i] * min) / TRANCHE_RATIO_GRANULARITY; + redeemableAmts[i] = MathUpgradeable.mulDiv(td.trancheRatios[i], minUnderlyingOut, TRANCHE_RATIO_GRANULARITY); } return (td, redeemableAmts);