-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'feat/tests' of github.com:morpho-labs/blue into feat/tests
- Loading branch information
Showing
4 changed files
with
175 additions
and
3 deletions.
There are no files selected for viewing
173 changes: 173 additions & 0 deletions
173
test/forge/integration/TestIntegrationAccrueInterests.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity 0.8.21; | ||
|
||
import "test/forge/BlueBase.t.sol"; | ||
|
||
contract IntegrationAccrueInterestsTest is BlueBaseTest { | ||
using FixedPointMathLib for uint256; | ||
|
||
function testAccrueInterestNoTimeElapsed(uint256 amountSupplied, uint256 amountBorrowed) public { | ||
amountSupplied = bound(amountSupplied, 2, 2 ** 64); | ||
amountBorrowed = bound(amountBorrowed, 1, amountSupplied); | ||
|
||
//set fee parameters | ||
vm.prank(OWNER); | ||
blue.setFeeRecipient(OWNER); | ||
|
||
borrowableAsset.setBalance(address(this), amountSupplied); | ||
blue.supply(market, amountSupplied, address(this), hex""); | ||
|
||
vm.prank(BORROWER); | ||
blue.borrow(market, amountBorrowed, BORROWER, BORROWER); | ||
|
||
uint256 totalBorrowBeforeAccrued = blue.totalBorrow(id); | ||
uint256 totalSupplyBeforeAccrued = blue.totalSupply(id); | ||
uint256 totalSupplySharesBeforeAccrued = blue.totalSupplyShares(id); | ||
|
||
//Supply then withdraw collateral to triger accrueInterests function | ||
collateralAsset.setBalance(address(this), 1); | ||
blue.supplyCollateral(market, 1, address(this), hex""); | ||
blue.withdrawCollateral(market, 1, address(this), address(this)); | ||
|
||
assertEq(blue.totalBorrow(id), totalBorrowBeforeAccrued, "total borrow"); | ||
assertEq(blue.totalSupply(id), totalSupplyBeforeAccrued, "total supply"); | ||
assertEq(blue.totalSupplyShares(id), totalSupplySharesBeforeAccrued, "total supply shares"); | ||
assertEq(blue.supplyShares(id, OWNER), 0, "feeRecipient's supply shares"); | ||
} | ||
|
||
function testAccrueInterestNoBorrow(uint256 amountSupplied, uint256 timeElapsed) public { | ||
amountSupplied = bound(amountSupplied, 2, 2 ** 64); | ||
timeElapsed = uint32(bound(timeElapsed, 1, type(uint32).max)); | ||
|
||
//set fee parameters | ||
vm.prank(OWNER); | ||
blue.setFeeRecipient(OWNER); | ||
|
||
borrowableAsset.setBalance(address(this), amountSupplied); | ||
blue.supply(market, amountSupplied, address(this), hex""); | ||
|
||
//new block | ||
vm.roll(block.number + 1); | ||
vm.warp(block.timestamp + timeElapsed); | ||
|
||
uint256 totalBorrowBeforeAccrued = blue.totalBorrow(id); | ||
uint256 totalSupplyBeforeAccrued = blue.totalSupply(id); | ||
uint256 totalSupplySharesBeforeAccrued = blue.totalSupplyShares(id); | ||
|
||
//Supply then withdraw collateral to triger accrueInterests function | ||
collateralAsset.setBalance(address(this), 1); | ||
blue.supplyCollateral(market, 1, address(this), hex""); | ||
blue.withdrawCollateral(market, 1, address(this), address(this)); | ||
|
||
assertEq(blue.totalBorrow(id), totalBorrowBeforeAccrued, "total borrow"); | ||
assertEq(blue.totalSupply(id), totalSupplyBeforeAccrued, "total supply"); | ||
assertEq(blue.totalSupplyShares(id), totalSupplySharesBeforeAccrued, "total supply shares"); | ||
assertEq(blue.supplyShares(id, OWNER), 0, "feeRecipient's supply shares"); | ||
assertEq(blue.lastUpdate(id), block.timestamp, "last update"); | ||
} | ||
|
||
function testAccrueInterestNoFee(uint256 amountSupplied, uint256 amountBorrowed, uint256 timeElapsed) public { | ||
amountSupplied = bound(amountSupplied, 2, 2 ** 64); | ||
amountBorrowed = bound(amountBorrowed, 1, amountSupplied); | ||
timeElapsed = uint32(bound(timeElapsed, 1, type(uint32).max)); | ||
|
||
//set fee parameters | ||
vm.prank(OWNER); | ||
blue.setFeeRecipient(OWNER); | ||
|
||
borrowableAsset.setBalance(address(this), amountSupplied); | ||
blue.supply(market, amountSupplied, address(this), hex""); | ||
|
||
vm.prank(BORROWER); | ||
blue.borrow(market, amountBorrowed, BORROWER, BORROWER); | ||
|
||
//new block | ||
vm.roll(block.number + 1); | ||
vm.warp(block.timestamp + timeElapsed); | ||
|
||
uint256 borrowRate = (blue.totalBorrow(id).divWadDown(blue.totalSupply(id))) / 365 days; | ||
uint256 totalBorrowBeforeAccrued = blue.totalBorrow(id); | ||
uint256 totalSupplyBeforeAccrued = blue.totalSupply(id); | ||
uint256 totalSupplySharesBeforeAccrued = blue.totalSupplyShares(id); | ||
uint256 expectedAccruedInterests = totalBorrowBeforeAccrued.mulWadDown(borrowRate * timeElapsed); | ||
|
||
//Supply then withdraw collateral to triger accrueInterests function | ||
collateralAsset.setBalance(address(this), 1); | ||
blue.supplyCollateral(market, 1, address(this), hex""); | ||
blue.withdrawCollateral(market, 1, address(this), address(this)); | ||
|
||
assertEq(blue.totalBorrow(id), totalBorrowBeforeAccrued + expectedAccruedInterests, "total borrow"); | ||
assertEq(blue.totalSupply(id), totalSupplyBeforeAccrued + expectedAccruedInterests, "total supply"); | ||
assertEq(blue.totalSupplyShares(id), totalSupplySharesBeforeAccrued, "total supply shares"); | ||
assertEq(blue.supplyShares(id, OWNER), 0, "feeRecipient's supply shares"); | ||
assertEq(blue.lastUpdate(id), block.timestamp, "last update"); | ||
} | ||
|
||
struct AccrueInterestWithFeesTestParams { | ||
uint256 borrowRate; | ||
uint256 totalBorrowBeforeAccrued; | ||
uint256 totalSupplyBeforeAccrued; | ||
uint256 totalSupplySharesBeforeAccrued; | ||
uint256 expectedAccruedInterests; | ||
uint256 feeAmount; | ||
uint256 feeShares; | ||
} | ||
|
||
function testAccrueInterestWithFees( | ||
uint256 amountSupplied, | ||
uint256 amountBorrowed, | ||
uint256 timeElapsed, | ||
uint256 fee | ||
) public { | ||
AccrueInterestWithFeesTestParams memory params; | ||
|
||
amountSupplied = bound(amountSupplied, 2, 2 ** 64); | ||
amountBorrowed = bound(amountBorrowed, 1, amountSupplied); | ||
timeElapsed = uint32(bound(timeElapsed, 1, type(uint32).max)); | ||
fee = bound(fee, 1, MAX_FEE); | ||
|
||
//set fee parameters | ||
vm.startPrank(OWNER); | ||
blue.setFeeRecipient(OWNER); | ||
blue.setFee(market, fee); | ||
vm.stopPrank(); | ||
|
||
borrowableAsset.setBalance(address(this), amountSupplied); | ||
blue.supply(market, amountSupplied, address(this), hex""); | ||
|
||
vm.prank(BORROWER); | ||
blue.borrow(market, amountBorrowed, BORROWER, BORROWER); | ||
|
||
//new block | ||
vm.roll(block.number + 1); | ||
vm.warp(block.timestamp + timeElapsed); | ||
|
||
params.borrowRate = (blue.totalBorrow(id).divWadDown(blue.totalSupply(id))) / 365 days; | ||
params.totalBorrowBeforeAccrued = blue.totalBorrow(id); | ||
params.totalSupplyBeforeAccrued = blue.totalSupply(id); | ||
params.totalSupplySharesBeforeAccrued = blue.totalSupplyShares(id); | ||
params.expectedAccruedInterests = params.totalBorrowBeforeAccrued.mulWadDown(params.borrowRate * timeElapsed); | ||
params.feeAmount = params.expectedAccruedInterests.mulWadDown(fee); | ||
params.feeShares = params.feeAmount.mulDivDown( | ||
params.totalSupplySharesBeforeAccrued, | ||
params.totalSupplyBeforeAccrued + params.expectedAccruedInterests - params.feeAmount | ||
); | ||
|
||
//Supply then withdraw collateral to triger accrueInterests function | ||
collateralAsset.setBalance(address(this), 1); | ||
blue.supplyCollateral(market, 1, address(this), hex""); | ||
blue.withdrawCollateral(market, 1, address(this), address(this)); | ||
|
||
assertEq( | ||
blue.totalBorrow(id), params.totalBorrowBeforeAccrued + params.expectedAccruedInterests, "total borrow" | ||
); | ||
assertEq( | ||
blue.totalSupply(id), params.totalSupplyBeforeAccrued + params.expectedAccruedInterests, "total supply" | ||
); | ||
assertEq( | ||
blue.totalSupplyShares(id), params.totalSupplySharesBeforeAccrued + params.feeShares, "total supply shares" | ||
); | ||
assertEq(blue.supplyShares(id, OWNER), params.feeShares, "feeRecipient's supply shares"); | ||
assertEq(blue.lastUpdate(id), block.timestamp, "last update"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters