diff --git a/test/escrowForkTests/BaseEscrowLPConvexTest.t.sol b/test/escrowForkTests/BaseEscrowLPConvexTest.t.sol index 902ed45f..3591a290 100644 --- a/test/escrowForkTests/BaseEscrowLPConvexTest.t.sol +++ b/test/escrowForkTests/BaseEscrowLPConvexTest.t.sol @@ -46,7 +46,6 @@ abstract contract BaseEscrowLPConvexTest is Test { struct ConvexInfo { uint256 pid; address rewardPool; - address depositToken; address stash; } @@ -62,7 +61,6 @@ abstract contract BaseEscrowLPConvexTest is Test { gauge = _gauge; pid = _convexInfo.pid; rewardPool = IRewardPool(_convexInfo.rewardPool); - depositToken = IERC20(_convexInfo.depositToken); stash = _convexInfo.stash; if (_addExtraDolaReward) { diff --git a/test/escrowForkTests/ConvexEscrowFork.t.sol b/test/escrowForkTests/ConvexEscrowFork.t.sol index 79267378..866c967e 100644 --- a/test/escrowForkTests/ConvexEscrowFork.t.sol +++ b/test/escrowForkTests/ConvexEscrowFork.t.sol @@ -5,9 +5,8 @@ import "forge-std/Test.sol"; import "src/escrows/ConvexEscrow.sol"; contract MockRewards { - IERC20 token; - constructor(address _token){ + constructor(address _token) { token = IERC20(_token); } @@ -16,25 +15,23 @@ contract MockRewards { } } -contract ConvexEscrowForkTest is Test{ - +contract ConvexEscrowForkTest is Test { address market = address(0xA); address beneficiary = address(0xB); address friend = address(0xC); - address holder = address(0x50BE13b54f3EeBBe415d20250598D81280e56772); + address holder = address(0x272b065A43EF59EA470fbfD9be76AD1b43aAB651); IERC20 dola = IERC20(0x865377367054516e17014CcdED1e7d814EDC9ce4); IERC20 cvx = IERC20(0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B); IERC20 cvxCrv = IERC20(0x62B9c7356A2Dc64a1969e19C23e4f579F9810Aa7); - ICvxRewardPool rewardPool = ICvxRewardPool(0xCF50b810E57Ac33B91dCF525C6ddd9881B139332); - - ConvexEscrow escrow; + ICvxRewardPool rewardPool = + ICvxRewardPool(0xCF50b810E57Ac33B91dCF525C6ddd9881B139332); + ConvexEscrow escrow; function setUp() public { //This will fail if there's no mainnet variable in foundry.toml string memory url = vm.rpcUrl("mainnet"); vm.createSelectFork(url, 22114296); - escrow = new ConvexEscrow(); vm.startPrank(market, market); escrow.initialize(address(cvx), beneficiary); @@ -46,13 +43,16 @@ contract ConvexEscrowForkTest is Test{ function testOnDeposit_successful_whenContractHoldsCvxCrv() public { uint balanceBefore = escrow.balance(); uint stakedBalanceBefore = rewardPool.balanceOf(address(escrow)); - + vm.prank(holder, holder); cvx.transfer(address(escrow), 1 ether); escrow.onDeposit(); assertEq(escrow.balance(), balanceBefore + 1 ether); - assertEq(rewardPool.balanceOf(address(escrow)), stakedBalanceBefore + 1 ether); + assertEq( + rewardPool.balanceOf(address(escrow)), + stakedBalanceBefore + 1 ether + ); } function testPay_successful_whenContractHasStakedCvxCrv() public { @@ -66,10 +66,15 @@ contract ConvexEscrowForkTest is Test{ vm.prank(market, market); escrow.pay(beneficiary, 1 ether); - assertEq(escrow.balance(), balanceBefore - 1 ether); - assertEq(rewardPool.balanceOf(address(escrow)), stakedBalanceBefore - 1 ether); - assertEq(cvx.balanceOf(beneficiary), beneficiaryBalanceBefore + 1 ether); + assertEq( + rewardPool.balanceOf(address(escrow)), + stakedBalanceBefore - 1 ether + ); + assertEq( + cvx.balanceOf(beneficiary), + beneficiaryBalanceBefore + 1 ether + ); } function testPay_failWithONLYMARKET_whenCalledByNonMarket() public { @@ -100,13 +105,17 @@ contract ConvexEscrowForkTest is Test{ vm.prank(holder, holder); cvx.transfer(address(escrow), 1 ether); escrow.onDeposit(); - + vm.startPrank(beneficiary); vm.warp(block.timestamp + 14 days); escrow.claim(); vm.stopPrank(); - assertGt(cvxCrv.balanceOf(beneficiary), cvxCrvBalanceBefore, "cvxCrv balance did not increase"); + assertGt( + cvxCrv.balanceOf(beneficiary), + cvxCrvBalanceBefore, + "cvxCrv balance did not increase" + ); } function testClaimTo_successful_whenExtraRewardsAdded() public { @@ -120,7 +129,7 @@ contract ConvexEscrowForkTest is Test{ deal(address(dola), address(reward), 10 ether); vm.prank(rewardPool.rewardManager()); rewardPool.addExtraReward(address(reward)); - + vm.startPrank(beneficiary); vm.warp(block.timestamp + 14 days); address[] memory rewards = new address[](1); @@ -128,8 +137,16 @@ contract ConvexEscrowForkTest is Test{ escrow.claimTo(beneficiary, rewards); vm.stopPrank(); - assertGt(cvxCrv.balanceOf(beneficiary), cvxCrvBalanceBefore, "cvxCrv balance did not increase"); - assertGt(dola.balanceOf(beneficiary), dolaBalanceBefore, "Dola extra reward balance did not increase"); + assertGt( + cvxCrv.balanceOf(beneficiary), + cvxCrvBalanceBefore, + "cvxCrv balance did not increase" + ); + assertGt( + dola.balanceOf(beneficiary), + dolaBalanceBefore, + "Dola extra reward balance did not increase" + ); } function testClaimTo_fails_whenTryingToClaimCollateral() public { @@ -141,7 +158,7 @@ contract ConvexEscrowForkTest is Test{ deal(address(cvx), address(reward), 10 ether); vm.prank(rewardPool.rewardManager()); rewardPool.addExtraReward(address(reward)); - + vm.startPrank(beneficiary); vm.warp(block.timestamp + 14 days); address[] memory rewards = new address[](1); @@ -160,7 +177,7 @@ contract ConvexEscrowForkTest is Test{ deal(address(cvx), address(reward), 10 ether); vm.prank(rewardPool.rewardManager()); rewardPool.addExtraReward(address(reward)); - + vm.startPrank(beneficiary); vm.warp(block.timestamp + 14 days); address[] memory rewards = new address[](2); @@ -237,10 +254,11 @@ contract ConvexEscrowForkTest is Test{ escrow.allowClaimOnBehalf(friend); } - function testDisallowClaimOnBehalf_fails_whenCalledByNonBeneficiary() public { + function testDisallowClaimOnBehalf_fails_whenCalledByNonBeneficiary() + public + { vm.prank(friend); vm.expectRevert("ONLY BENEFICIARY"); escrow.disallowClaimOnBehalf(friend); } - } diff --git a/test/escrowForkTests/CrvUSDDolaEscrowConvexFork.t.sol b/test/escrowForkTests/CrvUSDDolaEscrowConvexFork.t.sol index bd9ff15b..46d2d66b 100644 --- a/test/escrowForkTests/CrvUSDDolaEscrowConvexFork.t.sol +++ b/test/escrowForkTests/CrvUSDDolaEscrowConvexFork.t.sol @@ -12,7 +12,6 @@ contract DolaCrvUSDEscrowConvexForkTest is BaseEscrowLPConvexTest { // Convex uint256 _pid = 215; address _rewardPool = 0xC94208D230EEdC4cDC4F80141E21aA485A515660; - address _depositToken = 0x408abF1a02388A5EF19E3dB1e08db5eFdC510DFF; address _stash = 0x25F5Ccd892985Bf878327B15815bd90066EEf28d; function setUp() public { @@ -22,7 +21,6 @@ contract DolaCrvUSDEscrowConvexForkTest is BaseEscrowLPConvexTest { BaseEscrowLPConvexTest.ConvexInfo memory convexParams = ConvexInfo( _pid, _rewardPool, - _depositToken, _stash ); diff --git a/test/escrowForkTests/DolaDeUSDEscrowConvexFork.t.sol b/test/escrowForkTests/DolaDeUSDEscrowConvexFork.t.sol new file mode 100644 index 00000000..f08b2bf7 --- /dev/null +++ b/test/escrowForkTests/DolaDeUSDEscrowConvexFork.t.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {BaseEscrowLPConvexTest} from "test/escrowForkTests/BaseEscrowLPConvexTest.t.sol"; + +contract DolaDeUSDEscrowConvexForkTest is BaseEscrowLPConvexTest { + // Curve + address _dolaDeUSD = 0x6691DBb44154A9f23f8357C56FC9ff5548A8bdc4; + address _lpHolder = address(0xcb4a7b790eDB7Fa3e2731Efd7ED85275f92Fc74A); + address _gauge = 0xa48A3c91b062ca06Fd0d0569695432EB066f8c7E; + + // Convex + uint256 _pid = 419; + address _rewardPool = 0xD30E66cBc869Aa808eB9c81f8Aad8408767E3a3E; + address _stash = 0x074297Bf0dEA6925c27526E6E3E3151D8cE4edc7; + + function setUp() public { + //This will fail if there's no mainnet variable in foundry.toml + string memory url = vm.rpcUrl("mainnet"); + vm.createSelectFork(url, 21826229); + BaseEscrowLPConvexTest.ConvexInfo memory convexParams = ConvexInfo( + _pid, + _rewardPool, + _stash + ); + + init(_dolaDeUSD, _lpHolder, _gauge, convexParams, true); + } +} diff --git a/test/escrowForkTests/DolaFraxBPEscrowConvexFork.t.sol b/test/escrowForkTests/DolaFraxBPEscrowConvexFork.t.sol index 82b5e3f8..612bf062 100644 --- a/test/escrowForkTests/DolaFraxBPEscrowConvexFork.t.sol +++ b/test/escrowForkTests/DolaFraxBPEscrowConvexFork.t.sol @@ -12,7 +12,6 @@ contract DolaFraxBPEscrowConvexForkTest is BaseEscrowLPConvexTest { // Convex uint256 _pid = 115; address _rewardPool = 0x0404d05F3992347d2f0dC3a97bdd147D77C85c1c; - address _depositToken = 0xf7eCC27CC9DB5d28110AF2d89b176A6623c7E351; address _stash = 0xe5A980F96c791c8Ea56c2585840Cab571441510e; function setUp() public { @@ -22,7 +21,6 @@ contract DolaFraxBPEscrowConvexForkTest is BaseEscrowLPConvexTest { BaseEscrowLPConvexTest.ConvexInfo memory convexParams = ConvexInfo( _pid, _rewardPool, - _depositToken, _stash ); diff --git a/test/escrowForkTests/DolaFraxPyUSDEscrowConvexFork.t.sol b/test/escrowForkTests/DolaFraxPyUSDEscrowConvexFork.t.sol index 4531e4d5..ed3c0e59 100644 --- a/test/escrowForkTests/DolaFraxPyUSDEscrowConvexFork.t.sol +++ b/test/escrowForkTests/DolaFraxPyUSDEscrowConvexFork.t.sol @@ -12,7 +12,6 @@ contract DolaFraxPyUSDEscrowForkTest is BaseEscrowLPConvexTest { // Convex uint256 _pid = 317; address _rewardPool = 0xE8cBdBFD4A1D776AB1146B63ABD1718b2F92a823; - address _depositToken = 0x430bE19e180fd8c2199eC5FAEabE2F5CDba68C94; address _stash = 0x6bCc4b00F2Cc9CdFF935E1A5D939f26A233Dd381; function setUp() public { @@ -22,7 +21,6 @@ contract DolaFraxPyUSDEscrowForkTest is BaseEscrowLPConvexTest { BaseEscrowLPConvexTest.ConvexInfo memory convexParams = ConvexInfo( _pid, _rewardPool, - _depositToken, _stash ); diff --git a/test/escrowForkTests/DolaUSREscrowConvexFork.t.sol b/test/escrowForkTests/DolaUSREscrowConvexFork.t.sol new file mode 100644 index 00000000..3d222470 --- /dev/null +++ b/test/escrowForkTests/DolaUSREscrowConvexFork.t.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {BaseEscrowLPConvexTest} from "test/escrowForkTests/BaseEscrowLPConvexTest.t.sol"; + +contract DolaUSREscrowConvexForkTest is BaseEscrowLPConvexTest { + // Curve + address _dolaUSR = 0x38De22a3175708D45E7c7c64CD78479C8B56f76E; + address _lpHolder = address(0x89836bB3a0471adBa7DEf2677292c07004308Feb); + address _gauge = 0xd303994a0Db9b74f3E8fF629ba3097fC7060C331; + + // Convex + uint256 _pid = 421; + address _rewardPool = 0xE694a5e9272ea7ed2DC25f0c6D21640fb8a83166; + address _stash = 0x63A8AE4C4fE19B8816dEa970544F8a446051cB89; + + function setUp() public { + //This will fail if there's no mainnet variable in foundry.toml + string memory url = vm.rpcUrl("mainnet"); + vm.createSelectFork(url, 21969468); + BaseEscrowLPConvexTest.ConvexInfo memory convexParams = ConvexInfo( + _pid, + _rewardPool, + _stash + ); + + init(_dolaUSR, _lpHolder, _gauge, convexParams, true); + } +} diff --git a/test/feedForkTests/DolaDeUSDFeedFork.t.sol b/test/feedForkTests/DolaDeUSDFeedFork.t.sol new file mode 100644 index 00000000..3e8318e5 --- /dev/null +++ b/test/feedForkTests/DolaDeUSDFeedFork.t.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.19; + +import "forge-std/Test.sol"; +import "src/feeds/ChainlinkBasePriceFeed.sol"; +import {ChainlinkCurveFeed} from "src/feeds/ChainlinkCurveFeed.sol"; +import {ChainlinkCurve2CoinsFeed} from "src/feeds/ChainlinkCurve2CoinsFeed.sol"; +import "src/feeds/CurveLPPessimisticFeed.sol"; +import {DolaCurveLPPessimsticFeedBaseTest} from "test/feedForkTests/DolaCurveLPPessimsticFeedBaseTest.t.sol"; +import {ConfigAddr} from "test/ConfigAddr.sol"; + +contract DolaDeUSDFeedFork is DolaCurveLPPessimsticFeedBaseTest, ConfigAddr { + address clDeUSDFeed = address(0x471a6299C027Bd81ed4D66069dc510Bd0569f4F8); + uint256 deUSDHeartbeat = 86400; + + ICurvePool public constant dolaDeUSD = + ICurvePool(0x6691DBb44154A9f23f8357C56FC9ff5548A8bdc4); + + function setUp() public { + string memory url = vm.rpcUrl("mainnet"); + vm.createSelectFork(url, 21826229); + + ChainlinkBasePriceFeed deUSDFeed = new ChainlinkBasePriceFeed( + gov, + clDeUSDFeed, + address(0), + deUSDHeartbeat + ); + init(address(0), address(deUSDFeed), address(dolaDeUSD)); + } +} diff --git a/test/feedForkTests/DolaUSRFeedFork.t.sol b/test/feedForkTests/DolaUSRFeedFork.t.sol new file mode 100644 index 00000000..1cf8303e --- /dev/null +++ b/test/feedForkTests/DolaUSRFeedFork.t.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.19; + +import "forge-std/Test.sol"; +import "src/feeds/ChainlinkBasePriceFeed.sol"; +import {ChainlinkCurveFeed} from "src/feeds/ChainlinkCurveFeed.sol"; +import {ChainlinkCurve2CoinsFeed} from "src/feeds/ChainlinkCurve2CoinsFeed.sol"; +import "src/feeds/CurveLPPessimisticFeed.sol"; +import {DolaCurveLPPessimsticFeedBaseTest} from "test/feedForkTests/DolaCurveLPPessimsticFeedBaseTest.t.sol"; +import {ConfigAddr} from "test/ConfigAddr.sol"; + +contract DolaUSRFeedFork is DolaCurveLPPessimsticFeedBaseTest, ConfigAddr { + address clUSRFeed = address(0x34ad75691e25A8E9b681AAA85dbeB7ef6561B42c); + uint256 usrHeartbeat = 86400; + + ICurvePool public constant dolaUSR = + ICurvePool(0x38De22a3175708D45E7c7c64CD78479C8B56f76E); + + function setUp() public { + string memory url = vm.rpcUrl("mainnet"); + vm.createSelectFork(url, 21969468); + + ChainlinkBasePriceFeed usrFeed = new ChainlinkBasePriceFeed( + gov, + clUSRFeed, + address(0), + usrHeartbeat + ); + init(address(0), address(usrFeed), address(dolaUSR)); + } +} diff --git a/test/marketForkTests/DolaDeUSDConvexMarketForkTest.t.sol b/test/marketForkTests/DolaDeUSDConvexMarketForkTest.t.sol new file mode 100644 index 00000000..ad4c7865 --- /dev/null +++ b/test/marketForkTests/DolaDeUSDConvexMarketForkTest.t.sol @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {MarketBaseForkTest, IOracle, IDolaBorrowingRights, IERC20} from "./MarketBaseForkTest.sol"; +import {Market} from "src/Market.sol"; + +import {ConvexEscrowV2} from "src/escrows/ConvexEscrowV2.sol"; +import {CurveLPPessimisticFeed} from "src/feeds/CurveLPPessimisticFeed.sol"; +import {ChainlinkCurve2CoinsFeed, ICurvePool} from "src/feeds/ChainlinkCurve2CoinsFeed.sol"; +import {ChainlinkCurveFeed} from "src/feeds/ChainlinkCurveFeed.sol"; +import "src/feeds/ChainlinkBasePriceFeed.sol"; +import {console} from "forge-std/console.sol"; +import {YearnVaultV2Helper, IYearnVaultV2} from "src/util/YearnVaultV2Helper.sol"; +import {DolaFixedPriceFeed} from "src/feeds/DolaFixedPriceFeed.sol"; +import {ChainlinkBasePriceFeed} from "src/feeds/ChainlinkBasePriceFeed.sol"; + +contract DolaDeUSDConvexMarketForkTest is MarketBaseForkTest { + ConvexEscrowV2 escrow; + + CurveLPPessimisticFeed feedDolaDeUSD; + DolaFixedPriceFeed dolaFeed; + + ICurvePool public constant dolaDeUSD = + ICurvePool(0x6691DBb44154A9f23f8357C56FC9ff5548A8bdc4); + + address deUSDFeed = address(0x471a6299C027Bd81ed4D66069dc510Bd0569f4F8); + ChainlinkBasePriceFeed deUSDWrapper; + + address rewardPool = address(0xD30E66cBc869Aa808eB9c81f8Aad8408767E3a3E); + + address booster = address(0xF403C135812408BFbE8713b5A23a04b3D48AAE31); + + uint256 pid = 419; + + IERC20 public cvx = IERC20(0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B); + IERC20 public crv = IERC20(0xD533a949740bb3306d119CC777fa900bA034cd52); + + ConvexEscrowV2 userEscrow; + + function setUp() public virtual { + //This will fail if there's no mainnet variable in foundry.toml + string memory url = vm.rpcUrl("mainnet"); + vm.createSelectFork(url, 21826229); + escrow = new ConvexEscrowV2( + rewardPool, + booster, + address(cvx), + address(crv), + pid + ); + feedDolaDeUSD = _deployDolaDeUSDFeed(); + market = new Market( + gov, + fedAddr, + pauseGuardian, + address(escrow), + IDolaBorrowingRights(address(dbrAddr)), + IERC20(address(dolaDeUSD)), + IOracle(address(oracleAddr)), + 5000, + 5000, + 1000, + true + ); + _advancedInit(address(market), address(feedDolaDeUSD), true); + + userEscrow = ConvexEscrowV2( + address(Market(address(market)).predictEscrow(user)) + ); + } + + function test_escrow_immutables() public { + testDeposit(); + assertEq( + address(userEscrow.rewardPool()), + address(rewardPool), + "Reward pool not set" + ); + assertEq( + address(userEscrow.booster()), + address(booster), + "Booster not set" + ); + + assertEq(address(userEscrow.cvx()), address(cvx), "CVX not set"); + assertEq(address(userEscrow.crv()), address(crv), "CRV not set"); + } + + function _deployDolaDeUSDFeed() + internal + returns (CurveLPPessimisticFeed feed) + { + deUSDWrapper = new ChainlinkBasePriceFeed( + gov, + address(deUSDFeed), + address(0), + 1 + ); + feed = new CurveLPPessimisticFeed( + address(dolaDeUSD), + address(deUSDWrapper), + address(dolaFixedFeedAddr), + false + ); + } +} diff --git a/test/marketForkTests/DolaDeUSDYearnV2MarketForkTest.t.sol b/test/marketForkTests/DolaDeUSDYearnV2MarketForkTest.t.sol new file mode 100644 index 00000000..4b05bd92 --- /dev/null +++ b/test/marketForkTests/DolaDeUSDYearnV2MarketForkTest.t.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {MarketBaseForkTest, IOracle, IDolaBorrowingRights, IERC20} from "./MarketBaseForkTest.sol"; +import {Market} from "src/Market.sol"; +import {SimpleERC20Escrow} from "src/escrows/SimpleERC20Escrow.sol"; +import {CurveLPYearnV2Feed} from "src/feeds/CurveLPYearnV2Feed.sol"; +import {ChainlinkCurve2CoinsFeed} from "src/feeds/ChainlinkCurve2CoinsFeed.sol"; +import {ChainlinkCurveFeed, ICurvePool} from "src/feeds/ChainlinkCurveFeed.sol"; +import "src/feeds/ChainlinkBasePriceFeed.sol"; +import "src/feeds/CurveLPYearnV2Feed.sol"; +import {console} from "forge-std/console.sol"; +import {YearnVaultV2Helper, IYearnVaultV2} from "src/util/YearnVaultV2Helper.sol"; +import {CurveLPPessimisticFeed} from "src/feeds/CurveLPPessimisticFeed.sol"; +import {MockFeedDescription} from "test/mocks/MockFeedDescription.sol"; +import {ChainlinkBasePriceFeed} from "src/feeds/ChainlinkBasePriceFeed.sol"; + +contract DolaDeUSDYearnV2MarketForkTest is MarketBaseForkTest { + CurveLPYearnV2Feed yearnFeed; + CurveLPPessimisticFeed lpFeed; + + address deUSDFeed = address(0x471a6299C027Bd81ed4D66069dc510Bd0569f4F8); + ChainlinkBasePriceFeed deUSDWrapper; + ICurvePool public constant dolaDeUSD = + ICurvePool(0x6691DBb44154A9f23f8357C56FC9ff5548A8bdc4); + + address public constant yearn = + address(0xc7C1B907BCD3194C0D9bFA2125251af98BdDAfbb); + + function setUp() public virtual { + //This will fail if there's no mainnet variable in foundry.toml + string memory url = vm.rpcUrl("mainnet"); + vm.createSelectFork(url, 21826229); + + Market market = new Market( + gov, + lender, + pauseGuardian, + address(simpleERC20EscrowAddr), + IDolaBorrowingRights(address(dbr)), + IERC20(address(yearn)), + IOracle(address(oracle)), + 5000, + 5000, + 1000, + false + ); + yearnFeed = _deployDolaDeUSDYearnV2Feed(); + _advancedInit(address(market), address(yearnFeed), true); + } + + function _deployDolaDeUSDYearnV2Feed() + internal + returns (CurveLPYearnV2Feed feed) + { + deUSDWrapper = new ChainlinkBasePriceFeed( + gov, + address(deUSDFeed), + address(0), + 1 + ); + + lpFeed = new CurveLPPessimisticFeed( + address(dolaDeUSD), + address(deUSDWrapper), + address(dolaFixedFeedAddr), + false + ); + + feed = new CurveLPYearnV2Feed(address(yearn), address(lpFeed)); + } +} diff --git a/test/marketForkTests/DolaUSRConvexMarketForkTest.t.sol b/test/marketForkTests/DolaUSRConvexMarketForkTest.t.sol new file mode 100644 index 00000000..dc36e3f6 --- /dev/null +++ b/test/marketForkTests/DolaUSRConvexMarketForkTest.t.sol @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {MarketBaseForkTest, IOracle, IDolaBorrowingRights, IERC20} from "./MarketBaseForkTest.sol"; +import {Market} from "src/Market.sol"; + +import {ConvexEscrowV2} from "src/escrows/ConvexEscrowV2.sol"; +import {CurveLPPessimisticFeed} from "src/feeds/CurveLPPessimisticFeed.sol"; +import {ChainlinkCurve2CoinsFeed, ICurvePool} from "src/feeds/ChainlinkCurve2CoinsFeed.sol"; +import {ChainlinkCurveFeed} from "src/feeds/ChainlinkCurveFeed.sol"; +import "src/feeds/ChainlinkBasePriceFeed.sol"; +import {console} from "forge-std/console.sol"; +import {YearnVaultV2Helper, IYearnVaultV2} from "src/util/YearnVaultV2Helper.sol"; +import {DolaFixedPriceFeed} from "src/feeds/DolaFixedPriceFeed.sol"; +import {ChainlinkBasePriceFeed} from "src/feeds/ChainlinkBasePriceFeed.sol"; +import {MockFeedDescription} from "test/mocks/MockFeedDescription.sol"; + +contract DolaUSRConvexMarketForkTest is MarketBaseForkTest { + ConvexEscrowV2 escrow; + + CurveLPPessimisticFeed feedDolaUSR; + DolaFixedPriceFeed dolaFeed; + + ICurvePool public constant dolaUSR = + ICurvePool(0x38De22a3175708D45E7c7c64CD78479C8B56f76E); + + address public usrFeed = address(0x34ad75691e25A8E9b681AAA85dbeB7ef6561B42c); + + ChainlinkBasePriceFeed usrWrapper; + + address rewardPool = address(0xE694a5e9272ea7ed2DC25f0c6D21640fb8a83166); + + address booster = address(0xF403C135812408BFbE8713b5A23a04b3D48AAE31); + + uint256 pid = 421; + + IERC20 public cvx = IERC20(0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B); + IERC20 public crv = IERC20(0xD533a949740bb3306d119CC777fa900bA034cd52); + + ConvexEscrowV2 userEscrow; + + function setUp() public virtual { + //This will fail if there's no mainnet variable in foundry.toml + string memory url = vm.rpcUrl("mainnet"); + vm.createSelectFork(url, 21969468); + escrow = new ConvexEscrowV2( + rewardPool, + booster, + address(cvx), + address(crv), + pid + ); + feedDolaUSR = _deployDolaUSRFeed(); + market = new Market( + gov, + fedAddr, + pauseGuardian, + address(escrow), + IDolaBorrowingRights(address(dbrAddr)), + IERC20(address(dolaUSR)), + IOracle(address(oracleAddr)), + 5000, + 5000, + 1000, + true + ); + _advancedInit(address(market), address(feedDolaUSR), true); + + userEscrow = ConvexEscrowV2( + address(Market(address(market)).predictEscrow(user)) + ); + } + + function test_escrow_immutables() public { + testDeposit(); + assertEq( + address(userEscrow.rewardPool()), + address(rewardPool), + "Reward pool not set" + ); + assertEq( + address(userEscrow.booster()), + address(booster), + "Booster not set" + ); + + assertEq(address(userEscrow.cvx()), address(cvx), "CVX not set"); + assertEq(address(userEscrow.crv()), address(crv), "CRV not set"); + } + + function _deployDolaUSRFeed() + internal + returns (CurveLPPessimisticFeed feed) + { + + usrWrapper = new ChainlinkBasePriceFeed( + gov, + usrFeed, + address(0), + 86400 + ); + feed = new CurveLPPessimisticFeed( + address(dolaUSR), + address(usrWrapper), + address(dolaFixedFeedAddr), + false + ); + } +} diff --git a/test/marketForkTests/DolaUSRYearnV2MarketForkTest.t.sol b/test/marketForkTests/DolaUSRYearnV2MarketForkTest.t.sol new file mode 100644 index 00000000..c5df1389 --- /dev/null +++ b/test/marketForkTests/DolaUSRYearnV2MarketForkTest.t.sol @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {MarketBaseForkTest, IOracle, IDolaBorrowingRights, IERC20} from "./MarketBaseForkTest.sol"; +import {Market} from "src/Market.sol"; +import {SimpleERC20Escrow} from "src/escrows/SimpleERC20Escrow.sol"; +import {CurveLPYearnV2Feed} from "src/feeds/CurveLPYearnV2Feed.sol"; +import {ChainlinkCurve2CoinsFeed} from "src/feeds/ChainlinkCurve2CoinsFeed.sol"; +import {ChainlinkCurveFeed, ICurvePool} from "src/feeds/ChainlinkCurveFeed.sol"; +import "src/feeds/ChainlinkBasePriceFeed.sol"; +import "src/feeds/CurveLPYearnV2Feed.sol"; +import {console} from "forge-std/console.sol"; +import {YearnVaultV2Helper, IYearnVaultV2} from "src/util/YearnVaultV2Helper.sol"; +import {CurveLPPessimisticFeed} from "src/feeds/CurveLPPessimisticFeed.sol"; +import {MockFeedDescription} from "test/mocks/MockFeedDescription.sol"; +import {ChainlinkBasePriceFeed} from "src/feeds/ChainlinkBasePriceFeed.sol"; + +contract DolaUSRYearnV2MarketForkTest is MarketBaseForkTest { + CurveLPYearnV2Feed yearnFeed; + CurveLPPessimisticFeed lpFeed; + + address public usrFeed = address(0x34ad75691e25A8E9b681AAA85dbeB7ef6561B42c); + + ChainlinkBasePriceFeed usrWrapper; + + ICurvePool public constant dolaUSR = + ICurvePool(0x38De22a3175708D45E7c7c64CD78479C8B56f76E); + + address public constant yearn = + address(0x57a2c7925bAA1894a939f9f6721Ea33F2EcFD0e2); + + function setUp() public virtual { + //This will fail if there's no mainnet variable in foundry.toml + string memory url = vm.rpcUrl("mainnet"); + vm.createSelectFork(url, 21969468); + + Market market = new Market( + gov, + lender, + pauseGuardian, + address(simpleERC20EscrowAddr), + IDolaBorrowingRights(address(dbr)), + IERC20(address(yearn)), + IOracle(address(oracle)), + 5000, + 5000, + 1000, + false + ); + yearnFeed = _deployDolaUSRYearnV2Feed(); + _advancedInit(address(market), address(yearnFeed), true); + } + + function _deployDolaUSRYearnV2Feed() + internal + returns (CurveLPYearnV2Feed feed) + { + usrWrapper = new ChainlinkBasePriceFeed( + gov, + address(usrFeed), + address(0), + 86400 + ); + + lpFeed = new CurveLPPessimisticFeed( + address(dolaUSR), + address(usrWrapper), + address(dolaFixedFeedAddr), + false + ); + + feed = new CurveLPYearnV2Feed(address(yearn), address(lpFeed)); + } +} diff --git a/test/mocks/MockFeedDescription.sol b/test/mocks/MockFeedDescription.sol new file mode 100644 index 00000000..3b8ec72f --- /dev/null +++ b/test/mocks/MockFeedDescription.sol @@ -0,0 +1,51 @@ +pragma solidity ^0.8.13; + +interface IChainlinkFeed { + function decimals() external view returns (uint8); + function latestAnswer() external view returns (uint); +} + +contract Aggregator { + function maxAnswer() external pure returns (int192) { + return type(int192).max; + } + function minAnswer() external pure returns (int192) { + return type(int192).min; + } +} + +contract MockFeedDescription is IChainlinkFeed { + uint8 public decimals; + int price; + uint updatedAt; + string public description; + Aggregator public aggregator; + + constructor(uint8 _decimals, int _price, string memory _description) { + updatedAt = block.timestamp; + decimals = _decimals; + price = _price; + description = _description; + aggregator = new Aggregator(); + } + + function latestAnswer() external view returns (uint) { + return uint(price); + } + + function latestRoundData() + external + view + returns (uint80, int256, uint256, uint256, uint80) + { + return (0, price, 0, updatedAt, 0); + } + + function changeAnswer(uint _price) external { + price = int(_price); + } + + function changeUpdatedAt(uint _updatedAt) external { + updatedAt = _updatedAt; + } +} diff --git a/test/util/aleTests/ALEDolaDeUSD.t.sol b/test/util/aleTests/ALEDolaDeUSD.t.sol new file mode 100644 index 00000000..75a74a4b --- /dev/null +++ b/test/util/aleTests/ALEDolaDeUSD.t.sol @@ -0,0 +1,38 @@ +pragma solidity ^0.8.13; + +import {ICurvePool} from "src/interfaces/ICurvePool.sol"; +import {CurveDolaLPHelperDynamic} from "src/util/CurveDolaLPHelperDynamic.sol"; +import "test/marketForkTests/DolaDeUSDConvexMarketForkTest.t.sol"; +import {console} from "forge-std/console.sol"; +import {IMultiMarketTransformHelper} from "src/interfaces/IMultiMarketTransformHelper.sol"; +import {ALE} from "src/util/ALE.sol"; +import {ALEBaseDolaLPDynTest, IFlashMinter} from "test/util/aleTests/ALEBaseDolaLPDyn.sol"; + +contract ALEDolaDeUSDTest is + ALEBaseDolaLPDynTest, + DolaDeUSDConvexMarketForkTest +{ + function setUp() public override { + super.setUp(); + curvePool = dolaDeUSD; + + helper = new CurveDolaLPHelperDynamic( + gov, + pauseGuardian, + address(DOLA) + ); + + vm.startPrank(gov); + DOLA.mint(address(this), 100000 ether); + helper.setMarket(address(market), address(curvePool), 0, 2, address(0)); + ale = new ALE(address(0), triDBRAddr); + ale.setMarket(address(market), address(DOLA), address(helper), false); + + flash = IFlashMinter(address(ale.flash())); + flash.setMaxFlashLimit(100000 ether); + DOLA.addMinter(address(flash)); + borrowController.allow(address(ale)); + vm.stopPrank(); + userPkEscrow = address(market.predictEscrow(userPk)); + } +} diff --git a/test/util/aleTests/ALEDolaDeUSDYearnV2.t.sol b/test/util/aleTests/ALEDolaDeUSDYearnV2.t.sol new file mode 100644 index 00000000..14923ef4 --- /dev/null +++ b/test/util/aleTests/ALEDolaDeUSDYearnV2.t.sol @@ -0,0 +1,39 @@ +pragma solidity ^0.8.13; + +import {ICurvePool} from "src/interfaces/ICurvePool.sol"; +import {CurveDolaLPHelperDynamic} from "src/util/CurveDolaLPHelperDynamic.sol"; +import "test/marketForkTests/DolaDeUSDYearnV2MarketForkTest.t.sol"; +import {console} from "forge-std/console.sol"; +import {IMultiMarketTransformHelper} from "src/interfaces/IMultiMarketTransformHelper.sol"; +import {ALE} from "src/util/ALE.sol"; +import {YearnVaultV2Helper, IYearnVaultV2} from "src/util/YearnVaultV2Helper.sol"; +import {ALEBaseDolaLPDynYearnV2Test, IFlashMinter} from "test/util/aleTests/ALEBaseDolaLPDynYearnV2.sol"; + +contract ALEDolaDeUSDeYearnV2Test is + ALEBaseDolaLPDynYearnV2Test, + DolaDeUSDYearnV2MarketForkTest +{ + function setUp() public override { + super.setUp(); + + helper = new CurveDolaLPHelperDynamic( + gov, + pauseGuardian, + address(DOLA) + ); + curvePool = dolaDeUSD; + vault = IYearnVaultV2(yearn); + vm.startPrank(gov); + DOLA.mint(address(this), 100000 ether); + helper.setMarket(address(market), address(curvePool), 0, 2, yearn); + ale = new ALE(address(0), triDBRAddr); + ale.setMarket(address(market), address(DOLA), address(helper), false); + + flash = IFlashMinter(address(ale.flash())); + flash.setMaxFlashLimit(1000000 ether); + DOLA.addMinter(address(flash)); + borrowController.allow(address(ale)); + vm.stopPrank(); + userPkEscrow = address(market.predictEscrow(userPk)); + } +} diff --git a/test/util/aleTests/ALEDolaUSR.t.sol b/test/util/aleTests/ALEDolaUSR.t.sol new file mode 100644 index 00000000..560e90bd --- /dev/null +++ b/test/util/aleTests/ALEDolaUSR.t.sol @@ -0,0 +1,38 @@ +pragma solidity ^0.8.13; + +import {ICurvePool} from "src/interfaces/ICurvePool.sol"; +import {CurveDolaLPHelperDynamic} from "src/util/CurveDolaLPHelperDynamic.sol"; +import "test/marketForkTests/DolaUSRConvexMarketForkTest.t.sol"; +import {console} from "forge-std/console.sol"; +import {IMultiMarketTransformHelper} from "src/interfaces/IMultiMarketTransformHelper.sol"; +import {ALE} from "src/util/ALE.sol"; +import {ALEBaseDolaLPDynTest, IFlashMinter} from "test/util/aleTests/ALEBaseDolaLPDyn.sol"; + +contract ALEDolaUSRTest is + ALEBaseDolaLPDynTest, + DolaUSRConvexMarketForkTest +{ + function setUp() public override { + super.setUp(); + curvePool = dolaUSR; + + helper = new CurveDolaLPHelperDynamic( + gov, + pauseGuardian, + address(DOLA) + ); + + vm.startPrank(gov); + DOLA.mint(address(this), 100000 ether); + helper.setMarket(address(market), address(curvePool), 0, 2, address(0)); + ale = new ALE(address(0), triDBRAddr); + ale.setMarket(address(market), address(DOLA), address(helper), false); + + flash = IFlashMinter(address(ale.flash())); + flash.setMaxFlashLimit(100000 ether); + DOLA.addMinter(address(flash)); + borrowController.allow(address(ale)); + vm.stopPrank(); + userPkEscrow = address(market.predictEscrow(userPk)); + } +} diff --git a/test/util/aleTests/ALEDolaUSRYearnV2.t.sol b/test/util/aleTests/ALEDolaUSRYearnV2.t.sol new file mode 100644 index 00000000..b2b24544 --- /dev/null +++ b/test/util/aleTests/ALEDolaUSRYearnV2.t.sol @@ -0,0 +1,39 @@ +pragma solidity ^0.8.13; + +import {ICurvePool} from "src/interfaces/ICurvePool.sol"; +import {CurveDolaLPHelperDynamic} from "src/util/CurveDolaLPHelperDynamic.sol"; +import "test/marketForkTests/DolaUSRYearnV2MarketForkTest.t.sol"; +import {console} from "forge-std/console.sol"; +import {IMultiMarketTransformHelper} from "src/interfaces/IMultiMarketTransformHelper.sol"; +import {ALE} from "src/util/ALE.sol"; +import {YearnVaultV2Helper, IYearnVaultV2} from "src/util/YearnVaultV2Helper.sol"; +import {ALEBaseDolaLPDynYearnV2Test, IFlashMinter} from "test/util/aleTests/ALEBaseDolaLPDynYearnV2.sol"; + +contract ALEDolaUSRYearnV2Test is + ALEBaseDolaLPDynYearnV2Test, + DolaUSRYearnV2MarketForkTest +{ + function setUp() public override { + super.setUp(); + + helper = new CurveDolaLPHelperDynamic( + gov, + pauseGuardian, + address(DOLA) + ); + curvePool = dolaUSR; + vault = IYearnVaultV2(yearn); + vm.startPrank(gov); + DOLA.mint(address(this), 100000 ether); + helper.setMarket(address(market), address(curvePool), 0, 2, yearn); + ale = new ALE(address(0), triDBRAddr); + ale.setMarket(address(market), address(DOLA), address(helper), false); + + flash = IFlashMinter(address(ale.flash())); + flash.setMaxFlashLimit(1000000 ether); + DOLA.addMinter(address(flash)); + borrowController.allow(address(ale)); + vm.stopPrank(); + userPkEscrow = address(market.predictEscrow(userPk)); + } +}