From 1df9d53b45393faaf71d2f397b732dcd7e57dc84 Mon Sep 17 00:00:00 2001 From: Carson <carsonpcase@gmail.com> Date: Thu, 29 Aug 2024 14:14:55 -0400 Subject: [PATCH 1/6] chore: renamed math test file --- ...{RateMath.t.sol.working => RateMath.t.sol} | 86 ++++++++++++------- 1 file changed, 53 insertions(+), 33 deletions(-) rename test/{RateMath.t.sol.working => RateMath.t.sol} (73%) diff --git a/test/RateMath.t.sol.working b/test/RateMath.t.sol similarity index 73% rename from test/RateMath.t.sol.working rename to test/RateMath.t.sol index 4ac2bbd..eae31e6 100644 --- a/test/RateMath.t.sol.working +++ b/test/RateMath.t.sol @@ -5,22 +5,28 @@ import { FixedPointMathLib } from "@solmate/utils/FixedPointMathLib.sol"; import { ERC20 } from "@solmate/tokens/ERC20.sol"; import { Test, stdStorage, StdStorage, stdError, console } from "@forge-std/Test.sol"; -contract RateMath is Test{ +contract RateMath is Test { using FixedPointMathLib for uint256; uint256 ONE_SHARE; - uint exchangeRateInBase; - uint baseDecimals; - uint quoteDecimals; - uint quoteRateDecimals; - uint quoteRate; + uint256 exchangeRateInBase; + uint256 baseDecimals; + uint256 quoteDecimals; + uint256 quoteRateDecimals; + uint256 quoteRate; function setUp() external { // hard coded at 18 since in deploy script vault is set to 18 decimals, and this is set to that ONE_SHARE = 1e18; } - function testAtomicDepositAndWithdraw_18Decimals(uint depositAmount, uint256 startQuoteRate, uint256 startExchangeRate) external{ + function testAtomicDepositAndWithdraw_18Decimals( + uint256 depositAmount, + uint256 startQuoteRate, + uint256 startExchangeRate + ) + external + { // set decimals baseDecimals = 18; quoteDecimals = 18; @@ -32,16 +38,23 @@ contract RateMath is Test{ exchangeRateInBase = bound(startExchangeRate, 8e17, 2e18); // get shares out if deposit done - uint shares = depositAssetForShares(depositAmount); + uint256 shares = depositAssetForShares(depositAmount); // get assets back if all shares are withdrawn immediatelly - uint assetsBack = withdrawSharesForAssets(shares); + uint256 assetsBack = withdrawSharesForAssets(shares); assertFalse(assetsBack > depositAmount, "The assets back should not be > deposit amount when atomic"); assertApproxEqAbs(assetsBack, depositAmount, 2, "assetsBack != depositAmount when atomic"); } - function testDepositAndWithdrawWithRateChange_18Decimals(uint depositAmount, uint256 startQuoteRate, uint256 startExchangeRate, uint256 rateChange) external{ + function testDepositAndWithdrawWithRateChange_18Decimals( + uint256 depositAmount, + uint256 startQuoteRate, + uint256 startExchangeRate, + uint256 rateChange + ) + external + { // set decimals baseDecimals = 18; quoteDecimals = 18; @@ -51,18 +64,18 @@ contract RateMath is Test{ depositAmount = bound(depositAmount, 1, 100_000_000e18); quoteRate = bound(startQuoteRate, 1e18, 10_000e18); exchangeRateInBase = bound(startExchangeRate, 8e17, 2e18); - rateChange = bound(rateChange, 9_980, 10_020); + rateChange = bound(rateChange, 9980, 10_020); // get shares out if deposit done - uint shares = depositAssetForShares(depositAmount); - + uint256 shares = depositAssetForShares(depositAmount); + // update the rate according to rate change exchangeRateInBase = exchangeRateInBase.mulDivDown(rateChange, 10_000); // get assets back if all shares are withdrawn immediatelly - uint assetsBack = withdrawSharesForAssets(shares); + uint256 assetsBack = withdrawSharesForAssets(shares); - if(assetsBack > depositAmount){ + if (assetsBack > depositAmount) { console.log("Problem. assets back should not be > deposit amount"); console.log("AssetsBack: ", assetsBack); console.log("DepositAmount: ", depositAmount); @@ -72,7 +85,14 @@ contract RateMath is Test{ assertApproxEqAbs(assetsBack, depositAmount, 2, "assetsBack != depositAmount with rate change"); } - function testDepositAndWithdrawWithRateChange_18Decimals_Quote6(uint depositAmount, uint256 startQuoteRate, uint256 startExchangeRate, uint256 rateChange) external{ + function testDepositAndWithdrawWithRateChange_18Decimals_Quote6( + uint256 depositAmount, + uint256 startQuoteRate, + uint256 startExchangeRate, + uint256 rateChange + ) + external + { // set decimals baseDecimals = 18; quoteDecimals = 6; @@ -82,18 +102,18 @@ contract RateMath is Test{ depositAmount = bound(depositAmount, 1, 100_000_000e6); quoteRate = bound(startQuoteRate, 1e18, 10_000e18); exchangeRateInBase = bound(startExchangeRate, 8e17, 2e18); - rateChange = bound(rateChange, 9_980, 10_020); + rateChange = bound(rateChange, 9980, 10_020); // get shares out if deposit done - uint shares = depositAssetForShares(depositAmount); - + uint256 shares = depositAssetForShares(depositAmount); + // update the rate according to rate change exchangeRateInBase = exchangeRateInBase.mulDivDown(rateChange, 10_000); // get assets back if all shares are withdrawn immediatelly - uint assetsBack = withdrawSharesForAssets(shares); + uint256 assetsBack = withdrawSharesForAssets(shares); - if(assetsBack > depositAmount){ + if (assetsBack > depositAmount) { console.log("Problem. assets back should not be > deposit amount"); console.log("AssetsBack: ", assetsBack); console.log("DepositAmount: ", depositAmount); @@ -124,7 +144,8 @@ contract RateMath is Test{ // // calculate the assets out at the new rate // uint accountantRateAfter = accountant.getRateInQuoteSafe(ERC20(WEETH)); - // assertApproxEqAbs(accountantRateBefore.mulDivDown(rateChange, 10_000), accountantRateAfter, 1, "accountantRateBefore not equal to after with rate applied"); + // assertApproxEqAbs(accountantRateBefore.mulDivDown(rateChange, 10_000), accountantRateAfter, 1, + // "accountantRateBefore not equal to after with rate applied"); // console.log("Shares * Rate:\t", depositShares * accountantRateAfter); // console.log("one_share:\t\t", ONE_SHARE); // uint256 assetsOut = depositShares.mulDivDown(accountantRateAfter, (ONE_SHARE)); @@ -138,27 +159,27 @@ contract RateMath is Test{ // // getRateInQuoteSafe math"); // } - function withdrawSharesForAssets(uint shareAmount) public returns(uint assetsOut){ + function withdrawSharesForAssets(uint256 shareAmount) public returns (uint256 assetsOut) { assetsOut = shareAmount.mulDivDown(getRateInQuote(), ONE_SHARE); } - function depositAssetForShares(uint depositAmount) public returns(uint shares){ + function depositAssetForShares(uint256 depositAmount) public returns (uint256 shares) { if (depositAmount == 0) revert("depositAssetForShares amount = 0"); shares = depositAmount.mulDivDown(ONE_SHARE, getRateInQuote()); // if (shares < minimumMint) revert ("); } function getRateInQuote() public view returns (uint256 rateInQuote) { - uint256 exchangeRateInQuoteDecimals = changeDecimals(exchangeRateInBase, baseDecimals, quoteDecimals); + uint256 exchangeRateInQuoteDecimals = changeDecimals(exchangeRateInBase, baseDecimals, quoteDecimals); - uint256 oneQuote = 10 ** quoteDecimals; - rateInQuote = oneQuote.mulDivDown((exchangeRateInQuoteDecimals), quoteRate); - // console.log("Quote Rate: ",quoteRate); - // console.log("One Quote: ", oneQuote); - // console.log("Exchange Rate In Quote Decimals: ", exchangeRateInQuoteDecimals); + uint256 oneQuote = 10 ** quoteDecimals; + rateInQuote = oneQuote.mulDivDown((exchangeRateInQuoteDecimals), quoteRate); + // console.log("Quote Rate: ",quoteRate); + // console.log("One Quote: ", oneQuote); + // console.log("Exchange Rate In Quote Decimals: ", exchangeRateInQuoteDecimals); } - function changeDecimals(uint256 amount, uint fromDecimals, uint toDecimals) internal pure returns (uint256) { + function changeDecimals(uint256 amount, uint256 fromDecimals, uint256 toDecimals) internal pure returns (uint256) { if (fromDecimals == toDecimals) { return amount; } else if (fromDecimals < toDecimals) { @@ -167,5 +188,4 @@ contract RateMath is Test{ return amount / 10 ** (fromDecimals - toDecimals); } } - -} \ No newline at end of file +} From 37153f6598c6f5abbd81f2ff112ede801db92bda Mon Sep 17 00:00:00 2001 From: Carson <carsonpcase@gmail.com> Date: Thu, 29 Aug 2024 15:42:44 -0400 Subject: [PATCH 2/6] test: Work In Progress, for team to see --- test/LiveDeploy.t.sol | 2 +- test/RateMath.t.sol | 75 +++++++++++++++++++------------------------ 2 files changed, 34 insertions(+), 43 deletions(-) diff --git a/test/LiveDeploy.t.sol b/test/LiveDeploy.t.sol index c8ff380..c527d91 100644 --- a/test/LiveDeploy.t.sol +++ b/test/LiveDeploy.t.sol @@ -13,7 +13,7 @@ import { AccountantWithRateProviders } from "src/base/Roles/AccountantWithRatePr import { RolesAuthority } from "@solmate/auth/authorities/RolesAuthority.sol"; import { DeployRateProviders } from "script/deploy/01_DeployRateProviders.s.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; -import { StdJson } from "@forge-std/StdJson.sol"; +import { stdJson as StdJson } from "@forge-std/StdJson.sol"; import { CrossChainOPTellerWithMultiAssetSupportTest } from "test/CrossChain/CrossChainOPTellerWithMultiAssetSupport.t.sol"; diff --git a/test/RateMath.t.sol b/test/RateMath.t.sol index eae31e6..ab1a6a4 100644 --- a/test/RateMath.t.sol +++ b/test/RateMath.t.sol @@ -8,6 +8,10 @@ import { Test, stdStorage, StdStorage, stdError, console } from "@forge-std/Test contract RateMath is Test { using FixedPointMathLib for uint256; + // basis points + uint256 constant ACCEPTED_DELTA_PERCENT = 100; + + // keep some state variables that each test can change according to the scenario it's testing uint256 ONE_SHARE; uint256 exchangeRateInBase; uint256 baseDecimals; @@ -20,6 +24,20 @@ contract RateMath is Test { ONE_SHARE = 1e18; } + // started on a helper function for bounds + function boundValues( + uint256 depositAmount, + uint256 startQuoteRate, + uint256 startExchangeRate + ) + internal + returns (uint256 _depositAmount, uint256 _quoteRate, uint256 _exchangeRate) + { + _depositAmount = bound(depositAmount, 1, 100_000_000 * e(quoteDecimals)); + _quoteRate = bound(startQuoteRate, 1 * e(quoteRateDecimals - 2), 10 * e(quoteRateDecimals)); + _exchangeRate = bound(startExchangeRate, 8 * e(baseDecimals - 1), 2 * e(baseDecimals)); + } + function testAtomicDepositAndWithdraw_18Decimals( uint256 depositAmount, uint256 startQuoteRate, @@ -32,10 +50,8 @@ contract RateMath is Test { quoteDecimals = 18; quoteRateDecimals = 18; - // bound values - depositAmount = bound(depositAmount, 1, 100_000_000e18); - quoteRate = bound(startQuoteRate, 1e18, 10_000e18); - exchangeRateInBase = bound(startExchangeRate, 8e17, 2e18); + // bound values with helper function + (depositAmount, quoteRate, exchangeRateInBase) = boundValues(depositAmount, startQuoteRate, startExchangeRate); // get shares out if deposit done uint256 shares = depositAssetForShares(depositAmount); @@ -44,7 +60,12 @@ contract RateMath is Test { uint256 assetsBack = withdrawSharesForAssets(shares); assertFalse(assetsBack > depositAmount, "The assets back should not be > deposit amount when atomic"); - assertApproxEqAbs(assetsBack, depositAmount, 2, "assetsBack != depositAmount when atomic"); + assertApproxEqAbs( + assetsBack, + depositAmount, + depositAmount.mulDivUp(ACCEPTED_DELTA_PERCENT, 10_000), + "assetsBack != depositAmount when atomic" + ); } function testDepositAndWithdrawWithRateChange_18Decimals( @@ -85,6 +106,7 @@ contract RateMath is Test { assertApproxEqAbs(assetsBack, depositAmount, 2, "assetsBack != depositAmount with rate change"); } + // WIP testing with 6 decimals, not yet using helper function testDepositAndWithdrawWithRateChange_18Decimals_Quote6( uint256 depositAmount, uint256 startQuoteRate, @@ -120,45 +142,9 @@ contract RateMath is Test { console.log("Difference: ", assetsBack - depositAmount); } assertFalse(assetsBack > depositAmount, "The assets back should not be > deposit amount"); - //assertApproxEqAbs(assetsBack, depositAmount, 2, "assetsBack != depositAmount with rate change"); + assertApproxEqAbs(assetsBack, depositAmount, 2, "assetsBack != depositAmount with rate change"); } - // function testMath(uint256 depositAmount, uint256 rateChange) external { - // depositAmount = bound(depositAmount, 1, 1_000_000_000e18); - // rateChange = bound(rateChange, 9998, 10_002); - // // get the expected assets back after rate change - // uint256 expectedAssetsBack = ((depositAmount).mulDivDown(rateChange, 10_000)); - - // // get the shares back when depositing before rate change - // uint accountantRateBefore = accountant.getRateInQuoteSafe(ERC20(WEETH)); - // assertNotEq(accountantRateBefore, 1e18, "accountantRateBefore for WEETH equal to 1"); - // uint256 depositShares = depositAmount.mulDivDown(ONE_SHARE, accountantRateBefore); - // console.log("Shares * Rate:\t\t", depositShares * ONE_SHARE); - // console.log("accountantRateBefore:\t\t", accountantRateBefore); - - // // todo- atomic - // // change the rate - // uint96 newRate = uint96(accountant.getRate().mulDivDown(uint96(rateChange), 10_000)); - // vm.warp(1 days + block.timestamp); - // accountant.updateExchangeRate(newRate); - - // // calculate the assets out at the new rate - // uint accountantRateAfter = accountant.getRateInQuoteSafe(ERC20(WEETH)); - // assertApproxEqAbs(accountantRateBefore.mulDivDown(rateChange, 10_000), accountantRateAfter, 1, - // "accountantRateBefore not equal to after with rate applied"); - // console.log("Shares * Rate:\t", depositShares * accountantRateAfter); - // console.log("one_share:\t\t", ONE_SHARE); - // uint256 assetsOut = depositShares.mulDivDown(accountantRateAfter, (ONE_SHARE)); - - // // print if the expected > out and assert they're the same - // console.log("expectedAssetsBack >= realAssetsOut: ", expectedAssetsBack >= assetsOut); - // console.log("expectedAssetsBack: ", expectedAssetsBack); - // console.log("assetsOut: ", assetsOut); - // // assertTrue(expectedAssetsBack >= assetsOut, "BIG PROBLEM, not in protocol's favor"); - // assertApproxEqAbs(expectedAssetsBack, assetsOut, 1, "deposit * rateChange != depositAmount with"); - // // getRateInQuoteSafe math"); - // } - function withdrawSharesForAssets(uint256 shareAmount) public returns (uint256 assetsOut) { assetsOut = shareAmount.mulDivDown(getRateInQuote(), ONE_SHARE); } @@ -170,6 +156,7 @@ contract RateMath is Test { } function getRateInQuote() public view returns (uint256 rateInQuote) { + // exchangeRateInBase is called this because the rate provider will return decimals in that of base uint256 exchangeRateInQuoteDecimals = changeDecimals(exchangeRateInBase, baseDecimals, quoteDecimals); uint256 oneQuote = 10 ** quoteDecimals; @@ -188,4 +175,8 @@ contract RateMath is Test { return amount / 10 ** (fromDecimals - toDecimals); } } + + function e(uint256 decimals) internal returns (uint256) { + return (10 ** decimals); + } } From 9ffceab112e6ccdaea9627a6b4c935660aee1e34 Mon Sep 17 00:00:00 2001 From: Carson <carsonpcase@gmail.com> Date: Fri, 30 Aug 2024 15:41:01 -0400 Subject: [PATCH 3/6] test: jamie wbtc scenario --- test/RateMath.t.sol | 142 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 114 insertions(+), 28 deletions(-) diff --git a/test/RateMath.t.sol b/test/RateMath.t.sol index ab1a6a4..26d1026 100644 --- a/test/RateMath.t.sol +++ b/test/RateMath.t.sol @@ -9,14 +9,21 @@ contract RateMath is Test { using FixedPointMathLib for uint256; // basis points - uint256 constant ACCEPTED_DELTA_PERCENT = 100; + // accept 10% delta + uint256 constant ACCEPTED_DELTA_PERCENT = 1; // keep some state variables that each test can change according to the scenario it's testing uint256 ONE_SHARE; + + // exchange rate as reported in base decimals uint256 exchangeRateInBase; + // base asset decimals, ALSO the exchange rate decimals uint256 baseDecimals; + // the quote asset decimals uint256 quoteDecimals; + // decimals returned by rate provider uint256 quoteRateDecimals; + // quote rate returned by rate provider uint256 quoteRate; function setUp() external { @@ -33,11 +40,36 @@ contract RateMath is Test { internal returns (uint256 _depositAmount, uint256 _quoteRate, uint256 _exchangeRate) { - _depositAmount = bound(depositAmount, 1, 100_000_000 * e(quoteDecimals)); + /// NOTE rounding error is problematic with very small deposits, so start at 1e4 + _depositAmount = bound(depositAmount, 1 * e(quoteDecimals), 100_000_000 * e(quoteDecimals)); _quoteRate = bound(startQuoteRate, 1 * e(quoteRateDecimals - 2), 10 * e(quoteRateDecimals)); _exchangeRate = bound(startExchangeRate, 8 * e(baseDecimals - 1), 2 * e(baseDecimals)); } + /** + * here's the real test + * wbtc = 100,000 usdc on the dot, I have the quote rate from data provider return 10 do I get 1 share out if I + * deposit 100,000 usdc? you should + * now wbtc goes to 105,000 usdc, I withdraw one share and I should get 105,000 usdc...what do I actually get... + */ + function testJamieBTCScenario(uint256 depositAmount) external { + baseDecimals = 8; + quoteDecimals = 6; + quoteRateDecimals = 6; + + depositAmount = bound(depositAmount, 1 * e(quoteDecimals), 100_000_000 * e(quoteDecimals)); + quoteRate = 100_000 * e(quoteDecimals); + exchangeRateInBase = 1 * e(baseDecimals); + + uint256 shares = depositAssetForShares(depositAmount); + console.log("returned shares: ", shares); + + quoteRate = 105_000 * e(quoteDecimals); + + uint256 assetsBack = withdrawSharesForAssets(shares); + assertEq(assetsBack, 105_000 * e(quoteDecimals), "I withdraw one share and I should get 105,000 usdc"); + } + function testAtomicDepositAndWithdraw_18Decimals( uint256 depositAmount, uint256 startQuoteRate, @@ -63,7 +95,7 @@ contract RateMath is Test { assertApproxEqAbs( assetsBack, depositAmount, - depositAmount.mulDivUp(ACCEPTED_DELTA_PERCENT, 10_000), + depositAmount.mulDivDown(ACCEPTED_DELTA_PERCENT, 10_000), "assetsBack != depositAmount when atomic" ); } @@ -82,9 +114,7 @@ contract RateMath is Test { quoteRateDecimals = 18; // bound values - depositAmount = bound(depositAmount, 1, 100_000_000e18); - quoteRate = bound(startQuoteRate, 1e18, 10_000e18); - exchangeRateInBase = bound(startExchangeRate, 8e17, 2e18); + (depositAmount, quoteRate, exchangeRateInBase) = boundValues(depositAmount, startQuoteRate, startExchangeRate); rateChange = bound(rateChange, 9980, 10_020); // get shares out if deposit done @@ -95,19 +125,26 @@ contract RateMath is Test { // get assets back if all shares are withdrawn immediatelly uint256 assetsBack = withdrawSharesForAssets(shares); + uint256 newDepositAmountValue = depositAmount.mulDivDown(rateChange, 10_000); - if (assetsBack > depositAmount) { - console.log("Problem. assets back should not be > deposit amount"); + if (assetsBack > newDepositAmountValue) { + console.log("Problem. assets back should not be > deposit amount * rate change"); console.log("AssetsBack: ", assetsBack); - console.log("DepositAmount: ", depositAmount); - console.log("Difference: ", assetsBack - depositAmount); + console.log("NewDepositAmount: ", newDepositAmountValue); + console.log("Difference: ", assetsBack - newDepositAmountValue); } - assertFalse(assetsBack > depositAmount, "The assets back should not be > deposit amount"); - assertApproxEqAbs(assetsBack, depositAmount, 2, "assetsBack != depositAmount with rate change"); + assertApproxEqAbs( + assetsBack, + newDepositAmountValue, + newDepositAmountValue.mulDivDown(ACCEPTED_DELTA_PERCENT, 10_000), + "assetsBack != depositAmount with rate change" + ); + // assertFalse(assetsBack > newDepositAmountValue, "The assets back should not be > deposit amount * rate + // change"); } // WIP testing with 6 decimals, not yet using helper - function testDepositAndWithdrawWithRateChange_18Decimals_Quote6( + function testDepositAndWithdrawWithRateChange_6Decimals_Quote18( uint256 depositAmount, uint256 startQuoteRate, uint256 startExchangeRate, @@ -116,14 +153,57 @@ contract RateMath is Test { external { // set decimals - baseDecimals = 18; - quoteDecimals = 6; + baseDecimals = 6; + quoteDecimals = 18; quoteRateDecimals = 18; // bound values - depositAmount = bound(depositAmount, 1, 100_000_000e6); - quoteRate = bound(startQuoteRate, 1e18, 10_000e18); - exchangeRateInBase = bound(startExchangeRate, 8e17, 2e18); + (depositAmount, quoteRate, exchangeRateInBase) = boundValues(depositAmount, startQuoteRate, startExchangeRate); + rateChange = bound(rateChange, 9980, 10_020); + + // get shares out if deposit done + uint256 shares = depositAssetForShares(depositAmount); + + // update the rate according to rate change + exchangeRateInBase = exchangeRateInBase.mulDivDown(rateChange, 10_000); + uint256 newDepositAmountValue = depositAmount.mulDivDown(rateChange, 10_000); + + // get assets back if all shares are withdrawn immediatelly + uint256 assetsBack = withdrawSharesForAssets(shares); + + if (assetsBack > newDepositAmountValue) { + console.log("Problem. assets back should not be > deposit amount * rate change"); + console.log("AssetsBack: ", assetsBack); + console.log("NewDepositAmount: ", newDepositAmountValue); + console.log("Difference: ", assetsBack - newDepositAmountValue); + } + assertApproxEqAbs( + assetsBack, + newDepositAmountValue, + newDepositAmountValue.mulDivDown(ACCEPTED_DELTA_PERCENT, 10_000), + "assetsBack != depositAmount with rate change" + ); + // assertFalse(assetsBack > newDepositAmountValue, "The assets back should not be > deposit amount * rate + // change"); + } + + function testDepositAndWithdrawWithRateChange_FuzzDecimals( + uint256 depositAmount, + uint256 startQuoteRate, + uint256 startExchangeRate, + uint256 rateChange, + uint256 baseAssetDecimals, + uint256 quoteAssetDecimals + ) + external + { + // set decimals + baseDecimals = bound(baseAssetDecimals, 6, 18); + quoteDecimals = bound(baseAssetDecimals, 6, 18); + quoteRateDecimals = quoteDecimals; + + // bound values + (depositAmount, quoteRate, exchangeRateInBase) = boundValues(depositAmount, startQuoteRate, startExchangeRate); rateChange = bound(rateChange, 9980, 10_020); // get shares out if deposit done @@ -131,18 +211,25 @@ contract RateMath is Test { // update the rate according to rate change exchangeRateInBase = exchangeRateInBase.mulDivDown(rateChange, 10_000); + uint256 newDepositAmountValue = depositAmount.mulDivDown(rateChange, 10_000); // get assets back if all shares are withdrawn immediatelly uint256 assetsBack = withdrawSharesForAssets(shares); - if (assetsBack > depositAmount) { - console.log("Problem. assets back should not be > deposit amount"); + if (assetsBack > newDepositAmountValue) { + console.log("Problem. assets back should not be > deposit amount * rate change"); console.log("AssetsBack: ", assetsBack); - console.log("DepositAmount: ", depositAmount); - console.log("Difference: ", assetsBack - depositAmount); + console.log("NewDepositAmount: ", newDepositAmountValue); + console.log("Difference: ", assetsBack - newDepositAmountValue); } - assertFalse(assetsBack > depositAmount, "The assets back should not be > deposit amount"); - assertApproxEqAbs(assetsBack, depositAmount, 2, "assetsBack != depositAmount with rate change"); + assertApproxEqAbs( + assetsBack, + newDepositAmountValue, + newDepositAmountValue.mulDivDown(ACCEPTED_DELTA_PERCENT, 10_000), + "assetsBack != depositAmount with rate change" + ); + // assertFalse(assetsBack > newDepositAmountValue, "The assets back should not be > deposit amount * rate + // change"); } function withdrawSharesForAssets(uint256 shareAmount) public returns (uint256 assetsOut) { @@ -158,12 +245,11 @@ contract RateMath is Test { function getRateInQuote() public view returns (uint256 rateInQuote) { // exchangeRateInBase is called this because the rate provider will return decimals in that of base uint256 exchangeRateInQuoteDecimals = changeDecimals(exchangeRateInBase, baseDecimals, quoteDecimals); - uint256 oneQuote = 10 ** quoteDecimals; rateInQuote = oneQuote.mulDivDown((exchangeRateInQuoteDecimals), quoteRate); - // console.log("Quote Rate: ",quoteRate); - // console.log("One Quote: ", oneQuote); - // console.log("Exchange Rate In Quote Decimals: ", exchangeRateInQuoteDecimals); + console.log("Exchange Rate In Quote Decimals: ", exchangeRateInQuoteDecimals); + console.log("Quote Rate: ", quoteRate); + console.log("One Quote: ", oneQuote); } function changeDecimals(uint256 amount, uint256 fromDecimals, uint256 toDecimals) internal pure returns (uint256) { From 1954e861cc9303f248dfbf65c187264aca3e4e4b Mon Sep 17 00:00:00 2001 From: Carson <carsonpcase@gmail.com> Date: Fri, 30 Aug 2024 16:14:29 -0400 Subject: [PATCH 4/6] test: jamie btc scenario changes --- test/RateMath.t.sol | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/RateMath.t.sol b/test/RateMath.t.sol index 26d1026..77fd4d0 100644 --- a/test/RateMath.t.sol +++ b/test/RateMath.t.sol @@ -21,7 +21,7 @@ contract RateMath is Test { uint256 baseDecimals; // the quote asset decimals uint256 quoteDecimals; - // decimals returned by rate provider + // decimals returned by rate provider in base per quote uint256 quoteRateDecimals; // quote rate returned by rate provider uint256 quoteRate; @@ -42,6 +42,7 @@ contract RateMath is Test { { /// NOTE rounding error is problematic with very small deposits, so start at 1e4 _depositAmount = bound(depositAmount, 1 * e(quoteDecimals), 100_000_000 * e(quoteDecimals)); + // base per quote _quoteRate = bound(startQuoteRate, 1 * e(quoteRateDecimals - 2), 10 * e(quoteRateDecimals)); _exchangeRate = bound(startExchangeRate, 8 * e(baseDecimals - 1), 2 * e(baseDecimals)); } @@ -58,13 +59,14 @@ contract RateMath is Test { quoteRateDecimals = 6; depositAmount = bound(depositAmount, 1 * e(quoteDecimals), 100_000_000 * e(quoteDecimals)); - quoteRate = 100_000 * e(quoteDecimals); + // BASE PER QUOTE returning in quote decimals + quoteRate = 10; exchangeRateInBase = 1 * e(baseDecimals); uint256 shares = depositAssetForShares(depositAmount); console.log("returned shares: ", shares); - quoteRate = 105_000 * e(quoteDecimals); + quoteRate = 9; uint256 assetsBack = withdrawSharesForAssets(shares); assertEq(assetsBack, 105_000 * e(quoteDecimals), "I withdraw one share and I should get 105,000 usdc"); From 3d9635b7886d2ef8674fbbe0253d42fe47260e9d Mon Sep 17 00:00:00 2001 From: Carson <carsonpcase@gmail.com> Date: Wed, 4 Sep 2024 23:05:40 -0400 Subject: [PATCH 5/6] test: rate math --- .../form-lst-testnet-l1-08-30-24.json | 57 +++++ test/RateMath.t.sol | 236 ++++++++++-------- 2 files changed, 191 insertions(+), 102 deletions(-) create mode 100644 deployment-config/form-lst-testnet-l1-08-30-24.json diff --git a/deployment-config/form-lst-testnet-l1-08-30-24.json b/deployment-config/form-lst-testnet-l1-08-30-24.json new file mode 100644 index 0000000..ae8ec95 --- /dev/null +++ b/deployment-config/form-lst-testnet-l1-08-30-24.json @@ -0,0 +1,57 @@ +{ + "base": "0xee44150250AfF3E6aC25539765F056EDb7F85D7B", + "protocolAdmin": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "boringVaultAndBaseDecimals": "18", + "boringVault": { + "boringVaultSalt": "0x1ddd634c506ad203da17ff000000000000000000000000000000000000000013", + "boringVaultName": "Form LST", + "boringVaultSymbol": "FLST", + "address": "0x0000000000000000000000000000000000000000" + }, + "manager": { + "managerSalt": "0x30432d4b4ec00003b4a250000000000000000000000000000000000000000013", + "address": "0x0000000000000000000000000000000000000000" + }, + "accountant": { + "accountantSalt": "0x6a184dbea6f3cc0318679f000000000000000000000000000000000000000013", + "payoutAddress": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "allowedExchangeRateChangeUpper": "10003", + "allowedExchangeRateChangeLower": "9998", + "minimumUpdateDelayInSeconds": "3600", + "managementFee": "0", + "address": "0x0000000000000000000000000000000000000000" + }, + "teller": { + "tellerSalt": "0x51f8968749a56d01202c91000000000000000000000000000000000000000013", + "maxGasForPeer": 100000, + "minGasForPeer": 0, + "peerEid": 40270, + "tellerContractName": "TellerWithMultiAssetSupport", + "opMessenger": "0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef", + "assets": [], + "dvnIfNoDefault": { + "required": [ + "0x589dEDbD617e0CBcB916A9223F4d1300c294236b" + ], + "optional": [ + "0x380275805876Ff19055EA900CDb2B46a94ecF20D", + "0x8FafAE7Dd957044088b3d0F67359C327c6200d18", + "0xa59BA433ac34D2927232918Ef5B2eaAfcF130BA5", + "0xe552485d02EDd3067FE7FCbD4dd56BB1D3A998D2" + ], + "blockConfirmationsRequiredIfNoDefault": 15, + "optionalThreshold": 1 + }, + "address": "0x0000000000000000000000000000000000000000" + }, + "rolesAuthority": { + "rolesAuthoritySalt": "0x66bbc3b3b3000b01466a3a000000000000000000000000000000000000000013", + "strategist": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "exchangeRateBot": "0x0000000000417626Ef34D62C4DC189b021603f2F", + "address": "0x0000000000000000000000000000000000000000" + }, + "decoder": { + "decoderSalt": "0x48b53893da2e0b0248268c000000000000000000000000000000000000000013", + "address": "0x0000000000000000000000000000000000000000" + } +} \ No newline at end of file diff --git a/test/RateMath.t.sol b/test/RateMath.t.sol index 77fd4d0..bdaf522 100644 --- a/test/RateMath.t.sol +++ b/test/RateMath.t.sol @@ -8,9 +8,8 @@ import { Test, stdStorage, StdStorage, stdError, console } from "@forge-std/Test contract RateMath is Test { using FixedPointMathLib for uint256; - // basis points - // accept 10% delta - uint256 constant ACCEPTED_DELTA_PERCENT = 1; + uint256 constant ACCEPTED_DELTA_PERCENT_OUT_OF_FAVOR = 0.000015e18; + uint256 constant ACCEPTED_DELTA_PERCENT_IN_FAVOR = 0.01e18; // keep some state variables that each test can change according to the scenario it's testing uint256 ONE_SHARE; @@ -26,12 +25,6 @@ contract RateMath is Test { // quote rate returned by rate provider uint256 quoteRate; - function setUp() external { - // hard coded at 18 since in deploy script vault is set to 18 decimals, and this is set to that - ONE_SHARE = 1e18; - } - - // started on a helper function for bounds function boundValues( uint256 depositAmount, uint256 startQuoteRate, @@ -40,38 +33,14 @@ contract RateMath is Test { internal returns (uint256 _depositAmount, uint256 _quoteRate, uint256 _exchangeRate) { - /// NOTE rounding error is problematic with very small deposits, so start at 1e4 + // Bound Deposit 1 - 100,000,000 QuoteDecimals _depositAmount = bound(depositAmount, 1 * e(quoteDecimals), 100_000_000 * e(quoteDecimals)); - // base per quote + // Bound quote rate to 0.01 - 10 QuoteRateDecimals _quoteRate = bound(startQuoteRate, 1 * e(quoteRateDecimals - 2), 10 * e(quoteRateDecimals)); + // bound exchange rate to 0.8 - 2 baseDecimals _exchangeRate = bound(startExchangeRate, 8 * e(baseDecimals - 1), 2 * e(baseDecimals)); } - /** - * here's the real test - * wbtc = 100,000 usdc on the dot, I have the quote rate from data provider return 10 do I get 1 share out if I - * deposit 100,000 usdc? you should - * now wbtc goes to 105,000 usdc, I withdraw one share and I should get 105,000 usdc...what do I actually get... - */ - function testJamieBTCScenario(uint256 depositAmount) external { - baseDecimals = 8; - quoteDecimals = 6; - quoteRateDecimals = 6; - - depositAmount = bound(depositAmount, 1 * e(quoteDecimals), 100_000_000 * e(quoteDecimals)); - // BASE PER QUOTE returning in quote decimals - quoteRate = 10; - exchangeRateInBase = 1 * e(baseDecimals); - - uint256 shares = depositAssetForShares(depositAmount); - console.log("returned shares: ", shares); - - quoteRate = 9; - - uint256 assetsBack = withdrawSharesForAssets(shares); - assertEq(assetsBack, 105_000 * e(quoteDecimals), "I withdraw one share and I should get 105,000 usdc"); - } - function testAtomicDepositAndWithdraw_18Decimals( uint256 depositAmount, uint256 startQuoteRate, @@ -83,6 +52,7 @@ contract RateMath is Test { baseDecimals = 18; quoteDecimals = 18; quoteRateDecimals = 18; + ONE_SHARE = 10 ** baseDecimals; // bound values with helper function (depositAmount, quoteRate, exchangeRateInBase) = boundValues(depositAmount, startQuoteRate, startExchangeRate); @@ -92,17 +62,16 @@ contract RateMath is Test { // get assets back if all shares are withdrawn immediatelly uint256 assetsBack = withdrawSharesForAssets(shares); - - assertFalse(assetsBack > depositAmount, "The assets back should not be > deposit amount when atomic"); + assertTrue(assetsBack <= depositAmount, "Users should never get back more assets than they deposited"); assertApproxEqAbs( assetsBack, depositAmount, - depositAmount.mulDivDown(ACCEPTED_DELTA_PERCENT, 10_000), - "assetsBack != depositAmount when atomic" + depositAmount.mulDivDown(ACCEPTED_DELTA_PERCENT_IN_FAVOR, 1e18), + "assetsBack != depositAmount when atomic | In Favor" ); } - function testDepositAndWithdrawWithRateChange_18Decimals( + function testDepositAndWithdrawWithExchangeRateChange_18_6_Decimals( uint256 depositAmount, uint256 startQuoteRate, uint256 startExchangeRate, @@ -112,11 +81,15 @@ contract RateMath is Test { { // set decimals baseDecimals = 18; - quoteDecimals = 18; - quoteRateDecimals = 18; + quoteDecimals = 6; + quoteRateDecimals = 6; + ONE_SHARE = 10 ** baseDecimals; // bound values - (depositAmount, quoteRate, exchangeRateInBase) = boundValues(depositAmount, startQuoteRate, startExchangeRate); + (depositAmount, startQuoteRate, startExchangeRate) = + boundValues(depositAmount, startQuoteRate, startExchangeRate); + exchangeRateInBase = startExchangeRate; + quoteRate = startQuoteRate; rateChange = bound(rateChange, 9980, 10_020); // get shares out if deposit done @@ -127,26 +100,26 @@ contract RateMath is Test { // get assets back if all shares are withdrawn immediatelly uint256 assetsBack = withdrawSharesForAssets(shares); - uint256 newDepositAmountValue = depositAmount.mulDivDown(rateChange, 10_000); - - if (assetsBack > newDepositAmountValue) { - console.log("Problem. assets back should not be > deposit amount * rate change"); - console.log("AssetsBack: ", assetsBack); - console.log("NewDepositAmount: ", newDepositAmountValue); - console.log("Difference: ", assetsBack - newDepositAmountValue); + // get expected amount out + uint256 expected = (depositAmount * exchangeRateInBase * startQuoteRate) / (quoteRate * startExchangeRate); + + if (assetsBack > expected) { + assertApproxEqAbs( + assetsBack, + expected, + expected.mulDivDown(ACCEPTED_DELTA_PERCENT_OUT_OF_FAVOR, 1e18), + "assetsBack != depositAmount with rate change | Out Of Favor" + ); } assertApproxEqAbs( assetsBack, - newDepositAmountValue, - newDepositAmountValue.mulDivDown(ACCEPTED_DELTA_PERCENT, 10_000), - "assetsBack != depositAmount with rate change" + expected, + expected.mulDivDown(ACCEPTED_DELTA_PERCENT_IN_FAVOR, 1e18), + "assetsBack != depositAmount with rate change | In Favor" ); - // assertFalse(assetsBack > newDepositAmountValue, "The assets back should not be > deposit amount * rate - // change"); } - // WIP testing with 6 decimals, not yet using helper - function testDepositAndWithdrawWithRateChange_6Decimals_Quote18( + function testDepositAndWithdrawWithQuoteRateChange_18_6_Decimals( uint256 depositAmount, uint256 startQuoteRate, uint256 startExchangeRate, @@ -155,103 +128,161 @@ contract RateMath is Test { external { // set decimals - baseDecimals = 6; - quoteDecimals = 18; - quoteRateDecimals = 18; + baseDecimals = 18; + quoteDecimals = 6; + quoteRateDecimals = 6; + ONE_SHARE = 10 ** baseDecimals; // bound values - (depositAmount, quoteRate, exchangeRateInBase) = boundValues(depositAmount, startQuoteRate, startExchangeRate); + (depositAmount, startQuoteRate, startExchangeRate) = + boundValues(depositAmount, startQuoteRate, startExchangeRate); + exchangeRateInBase = startExchangeRate; + quoteRate = startQuoteRate; rateChange = bound(rateChange, 9980, 10_020); // get shares out if deposit done uint256 shares = depositAssetForShares(depositAmount); // update the rate according to rate change - exchangeRateInBase = exchangeRateInBase.mulDivDown(rateChange, 10_000); - uint256 newDepositAmountValue = depositAmount.mulDivDown(rateChange, 10_000); + quoteRate = quoteRate.mulDivDown(rateChange, 10_000); // get assets back if all shares are withdrawn immediatelly uint256 assetsBack = withdrawSharesForAssets(shares); - if (assetsBack > newDepositAmountValue) { - console.log("Problem. assets back should not be > deposit amount * rate change"); - console.log("AssetsBack: ", assetsBack); - console.log("NewDepositAmount: ", newDepositAmountValue); - console.log("Difference: ", assetsBack - newDepositAmountValue); + // get expected amount out + uint256 expected = (depositAmount * exchangeRateInBase * startQuoteRate) / (quoteRate * startExchangeRate); + + if (assetsBack > expected) { + assertApproxEqAbs( + assetsBack, + expected, + expected.mulDivDown(ACCEPTED_DELTA_PERCENT_OUT_OF_FAVOR, 1e18), + "assetsBack != depositAmount with rate change | Out Of Favor" + ); } assertApproxEqAbs( assetsBack, - newDepositAmountValue, - newDepositAmountValue.mulDivDown(ACCEPTED_DELTA_PERCENT, 10_000), - "assetsBack != depositAmount with rate change" + expected, + expected.mulDivDown(ACCEPTED_DELTA_PERCENT_IN_FAVOR, 1e18), + "assetsBack != depositAmount with rate change | In Favor" ); - // assertFalse(assetsBack > newDepositAmountValue, "The assets back should not be > deposit amount * rate - // change"); } - function testDepositAndWithdrawWithRateChange_FuzzDecimals( + function testDepositAndWithdrawWithAllFuzzed_18_decimals( uint256 depositAmount, uint256 startQuoteRate, uint256 startExchangeRate, - uint256 rateChange, - uint256 baseAssetDecimals, - uint256 quoteAssetDecimals + uint256 exchangeRateChange, + uint256 quoteRateChange ) external { // set decimals - baseDecimals = bound(baseAssetDecimals, 6, 18); - quoteDecimals = bound(baseAssetDecimals, 6, 18); + baseDecimals = 18; + quoteDecimals = 18; quoteRateDecimals = quoteDecimals; + ONE_SHARE = 10 ** baseDecimals; // bound values - (depositAmount, quoteRate, exchangeRateInBase) = boundValues(depositAmount, startQuoteRate, startExchangeRate); - rateChange = bound(rateChange, 9980, 10_020); + (depositAmount, startQuoteRate, startExchangeRate) = + boundValues(depositAmount, startQuoteRate, startExchangeRate); + exchangeRateInBase = startExchangeRate; + quoteRate = startQuoteRate; + exchangeRateChange = bound(exchangeRateChange, 5980, 20_020); + quoteRateChange = bound(quoteRateChange, 5980, 20_020); // get shares out if deposit done uint256 shares = depositAssetForShares(depositAmount); // update the rate according to rate change - exchangeRateInBase = exchangeRateInBase.mulDivDown(rateChange, 10_000); - uint256 newDepositAmountValue = depositAmount.mulDivDown(rateChange, 10_000); + exchangeRateInBase = exchangeRateInBase.mulDivDown(exchangeRateChange, 10_000); + quoteRate = quoteRate.mulDivDown(quoteRateChange, 10_000); + + uint256 expected = (depositAmount * exchangeRateInBase * startQuoteRate) / (quoteRate * startExchangeRate); + + // get assets back if all shares are withdrawn immediatelly + uint256 assetsBack = withdrawSharesForAssets(shares); + + if (assetsBack > expected) { + assertApproxEqAbs( + assetsBack, + expected, + expected.mulDivDown(ACCEPTED_DELTA_PERCENT_OUT_OF_FAVOR, 1e18), + "assetsBack != depositAmount with rate change | Out Of Favor" + ); + } + assertApproxEqAbs( + assetsBack, + expected, + expected.mulDivDown(ACCEPTED_DELTA_PERCENT_IN_FAVOR, 1e18), + "assetsBack != depositAmount with rate change | In Favor" + ); + } + + function testDepositAndWithdrawWithAllFuzzed_18_6_decimals( + uint256 depositAmount, + uint256 startQuoteRate, + uint256 startExchangeRate, + uint256 exchangeRateChange, + uint256 quoteRateChange + ) + external + { + // set decimals + baseDecimals = 18; + quoteDecimals = 6; + quoteRateDecimals = quoteDecimals; + ONE_SHARE = 10 ** baseDecimals; + + // bound values + (depositAmount, startQuoteRate, startExchangeRate) = + boundValues(depositAmount, startQuoteRate, startExchangeRate); + exchangeRateInBase = startExchangeRate; + quoteRate = startQuoteRate; + exchangeRateChange = bound(exchangeRateChange, 5980, 20_020); + quoteRateChange = bound(quoteRateChange, 5980, 20_020); + + // get shares out if deposit done + uint256 shares = depositAssetForShares(depositAmount); + + // update the rate according to rate change + exchangeRateInBase = exchangeRateInBase.mulDivDown(exchangeRateChange, 10_000); + quoteRate = quoteRate.mulDivDown(quoteRateChange, 10_000); + + uint256 expected = (depositAmount * exchangeRateInBase * startQuoteRate) / (quoteRate * startExchangeRate); // get assets back if all shares are withdrawn immediatelly uint256 assetsBack = withdrawSharesForAssets(shares); - if (assetsBack > newDepositAmountValue) { - console.log("Problem. assets back should not be > deposit amount * rate change"); - console.log("AssetsBack: ", assetsBack); - console.log("NewDepositAmount: ", newDepositAmountValue); - console.log("Difference: ", assetsBack - newDepositAmountValue); + if (assetsBack > expected) { + assertApproxEqAbs( + assetsBack, + expected, + expected.mulDivDown(ACCEPTED_DELTA_PERCENT_OUT_OF_FAVOR, 1e18), + "assetsBack != depositAmount with rate change | Out Of Favor" + ); } assertApproxEqAbs( assetsBack, - newDepositAmountValue, - newDepositAmountValue.mulDivDown(ACCEPTED_DELTA_PERCENT, 10_000), - "assetsBack != depositAmount with rate change" + expected, + expected.mulDivDown(ACCEPTED_DELTA_PERCENT_IN_FAVOR, 1e18), + "assetsBack != depositAmount with rate change | In Favor" ); - // assertFalse(assetsBack > newDepositAmountValue, "The assets back should not be > deposit amount * rate - // change"); } - function withdrawSharesForAssets(uint256 shareAmount) public returns (uint256 assetsOut) { + function withdrawSharesForAssets(uint256 shareAmount) public view returns (uint256 assetsOut) { assetsOut = shareAmount.mulDivDown(getRateInQuote(), ONE_SHARE); } - function depositAssetForShares(uint256 depositAmount) public returns (uint256 shares) { + function depositAssetForShares(uint256 depositAmount) public view returns (uint256 shares) { if (depositAmount == 0) revert("depositAssetForShares amount = 0"); shares = depositAmount.mulDivDown(ONE_SHARE, getRateInQuote()); - // if (shares < minimumMint) revert ("); } function getRateInQuote() public view returns (uint256 rateInQuote) { - // exchangeRateInBase is called this because the rate provider will return decimals in that of base uint256 exchangeRateInQuoteDecimals = changeDecimals(exchangeRateInBase, baseDecimals, quoteDecimals); uint256 oneQuote = 10 ** quoteDecimals; rateInQuote = oneQuote.mulDivDown((exchangeRateInQuoteDecimals), quoteRate); - console.log("Exchange Rate In Quote Decimals: ", exchangeRateInQuoteDecimals); - console.log("Quote Rate: ", quoteRate); - console.log("One Quote: ", oneQuote); } function changeDecimals(uint256 amount, uint256 fromDecimals, uint256 toDecimals) internal pure returns (uint256) { @@ -264,7 +295,8 @@ contract RateMath is Test { } } - function e(uint256 decimals) internal returns (uint256) { + /// @dev Helper function to preform 10**x + function e(uint256 decimals) internal pure returns (uint256) { return (10 ** decimals); } } From 03645523392fd066abee8e8d1d7737633560139e Mon Sep 17 00:00:00 2001 From: Carson <carsonpcase@gmail.com> Date: Thu, 5 Sep 2024 22:47:51 -0400 Subject: [PATCH 6/6] refactor: codespell --- lzConfigCheck.cjs | 2 +- test/RateMath.t.sol | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/lzConfigCheck.cjs b/lzConfigCheck.cjs index 45911fe..537f1cd 100644 --- a/lzConfigCheck.cjs +++ b/lzConfigCheck.cjs @@ -113,7 +113,7 @@ async function main() { const chain2 = findings2.findings[0].chain; for (const finding of findings2.findings) { - assert(providers1.includes(finding.provider), "Provider: "+finding.provider+" does not havea matching provider in the first config"); + assert(providers1.includes(finding.provider), "Provider: "+finding.provider+" does not have a matching provider in the first config"); assert(finding.chain == chain2, "Networks do not match for: "+finding); } diff --git a/test/RateMath.t.sol b/test/RateMath.t.sol index bdaf522..4dca134 100644 --- a/test/RateMath.t.sol +++ b/test/RateMath.t.sol @@ -60,7 +60,7 @@ contract RateMath is Test { // get shares out if deposit done uint256 shares = depositAssetForShares(depositAmount); - // get assets back if all shares are withdrawn immediatelly + // get assets back if all shares are withdrawn immediately uint256 assetsBack = withdrawSharesForAssets(shares); assertTrue(assetsBack <= depositAmount, "Users should never get back more assets than they deposited"); assertApproxEqAbs( @@ -98,7 +98,6 @@ contract RateMath is Test { // update the rate according to rate change exchangeRateInBase = exchangeRateInBase.mulDivDown(rateChange, 10_000); - // get assets back if all shares are withdrawn immediatelly uint256 assetsBack = withdrawSharesForAssets(shares); // get expected amount out uint256 expected = (depositAmount * exchangeRateInBase * startQuoteRate) / (quoteRate * startExchangeRate); @@ -146,7 +145,6 @@ contract RateMath is Test { // update the rate according to rate change quoteRate = quoteRate.mulDivDown(rateChange, 10_000); - // get assets back if all shares are withdrawn immediatelly uint256 assetsBack = withdrawSharesForAssets(shares); // get expected amount out @@ -200,7 +198,6 @@ contract RateMath is Test { uint256 expected = (depositAmount * exchangeRateInBase * startQuoteRate) / (quoteRate * startExchangeRate); - // get assets back if all shares are withdrawn immediatelly uint256 assetsBack = withdrawSharesForAssets(shares); if (assetsBack > expected) { @@ -251,7 +248,6 @@ contract RateMath is Test { uint256 expected = (depositAmount * exchangeRateInBase * startQuoteRate) / (quoteRate * startExchangeRate); - // get assets back if all shares are withdrawn immediatelly uint256 assetsBack = withdrawSharesForAssets(shares); if (assetsBack > expected) { @@ -295,7 +291,7 @@ contract RateMath is Test { } } - /// @dev Helper function to preform 10**x + /// @dev Helper function to perform 10**x function e(uint256 decimals) internal pure returns (uint256) { return (10 ** decimals); }