Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
larryob committed Oct 19, 2023
1 parent d272047 commit 3465627
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 20 deletions.
6 changes: 6 additions & 0 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,12 @@ SthEthLevPolygon_IntegrationTest:testPerformanceFee() (gas: 775743)
SthEthLevPolygon_IntegrationTest:testVaultPause() (gas: 391282)
SthEthLevPolygon_IntegrationTest:testWithdrawalFee() (gas: 313482)
SthEthLevPolygon_IntegrationTest:testWithdrawalFeeWithNft() (gas: 1259503)
StrikeEthStrategyTest:testAddToPosition() (gas: 522476)
StrikeEthStrategyTest:testClosePosition() (gas: 756205)
StrikeEthStrategyTest:testLeverage() (gas: 539253)
StrikeEthStrategyTest:testMutateTotalLockedValue() (gas: 834439)
StrikeEthStrategyTest:testSetParams() (gas: 14303)
StrikeEthStrategyTest:testTotalLockedValue() (gas: 553314)
TestBeefyAeroStrategy:testDepositAndWithdrawFromVault() (gas: 2013214)
TestBeefyAeroStrategy:testDivestByStrategist() (gas: 1629793)
TestBeefyAeroStrategy:testDivestHalf() (gas: 342116)
Expand Down
27 changes: 14 additions & 13 deletions src/strategies/StrikeEthStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ contract StrikeEthStrategy is AccessStrategy, IFlashLoanRecipient {
}

error onlyBalancerVault();
/// @notice Callback called by balancer vault after flashloan is initiated.

/// @notice Callback called by balancer vault after flashloan is initiated.
function receiveFlashLoan(
ERC20[] memory, /* tokens */
uint256[] memory amounts,
Expand All @@ -55,6 +55,9 @@ contract StrikeEthStrategy is AccessStrategy, IFlashLoanRecipient {

uint256 ethBorrowed = amounts[0];

// Convert wETH to ETH
WETH.withdraw(ethBorrowed);

(LoanType loan) = abi.decode(userData, (LoanType));

if (loan == LoanType.divest) {
Expand All @@ -81,15 +84,12 @@ contract StrikeEthStrategy is AccessStrategy, IFlashLoanRecipient {
recipient: IFlashLoanRecipient(address(this)),
tokens: tokens,
amounts: amounts,
userData: abi.encode(LoanType.invest, address(0))
userData: abi.encode(LoanType.invest)
});
}

/// @dev Add to leveraged position. Trade ETH to wstETH, deposit in AAVE, and borrow to repay balancer loan.
/// @dev Add to leveraged position. Deposit into compound and borrow to repay balancer loan.
function _addToPosition(uint256 ethBorrowed) internal {
// Convert wETH to ETH
WETH.withdraw(ethBorrowed);

// Deposit ETH into compound
cToken.mint{value: ethBorrowed}();

Expand All @@ -98,30 +98,28 @@ contract StrikeEthStrategy is AccessStrategy, IFlashLoanRecipient {
uint256 borrowRes = cToken.borrow(amountToBorrow);
if (borrowRes != 0) revert CompBorrowError(borrowRes);

// convert to wETH to pay back balancer loan
// Convert ETH to wETH for balancer repayment
WETH.deposit{value: amountToBorrow}();
}

/// @dev We need this to receive ETH when calling wETH.withdraw()
receive() external payable {}

/// @dev Unlock wstETH collateral via flashloan, then repay balancer loan with unlocked collateral.
/// @dev Unlock ETH collateral via flashloan, then repay balancer loan with unlocked collateral.
function _divest(uint256 amount) internal override returns (uint256) {
uint256 ethNeeded = _getDivestFlashLoanAmounts(amount);

ERC20[] memory tokens = new ERC20[](1);
tokens[0] = WETH;

uint256[] memory amounts = new uint256[](1);
amounts[0] = ethNeeded;
amounts[0] = _getDivestFlashLoanAmounts(amount);

uint256 origAssets = WETH.balanceOf(address(this));

BALANCER.flashLoan({
recipient: IFlashLoanRecipient(address(this)),
tokens: tokens,
amounts: amounts,
userData: abi.encode(LoanType.divest, address(0))
userData: abi.encode(LoanType.divest)
});

// The loan has been paid, any other unlocked collateral belongs to user
Expand Down Expand Up @@ -151,6 +149,9 @@ contract StrikeEthStrategy is AccessStrategy, IFlashLoanRecipient {
// Withdraw same proportion of collateral from aave
uint256 res = cToken.redeemUnderlying(ethToRedeem);
if (res != 0) revert CompRedeemError(res);

// Convert ETH to wETH for balancer repayment and payment to user
WETH.deposit{value: ethToRedeem}();
}

/*//////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -187,7 +188,7 @@ contract StrikeEthStrategy is AccessStrategy, IFlashLoanRecipient {
error CompRedeemError(uint256 errorCode);

/// @notice The leverage factor of the position multiplied by 100. E.g. 150 would be 1.5x leverage.
uint256 public leverage = 992; // 9.92x
uint256 public leverage = 333; // 3.33x

/// @notice Set the leverage factor.
/// @param _leverage The new leverage.
Expand Down
8 changes: 1 addition & 7 deletions src/test/LidoLevL2.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,7 @@ import {TestPlus} from "./TestPlus.sol";
import {stdStorage, StdStorage} from "forge-std/Test.sol";

import {ERC20} from "solmate/src/tokens/ERC20.sol";
import {
LidoLevL2,
IBalancerVault,
IFlashLoanRecipient,
AffineVault,
FixedPointMathLib
} from "src/strategies/LidoLevL2.sol";
import {LidoLevL2, AffineVault, FixedPointMathLib} from "src/strategies/LidoLevL2.sol";

import {console2} from "forge-std/console2.sol";

Expand Down
107 changes: 107 additions & 0 deletions src/test/StrikeEthStrategy.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.16;

import {TestPlus} from "./TestPlus.sol";
import {stdStorage, StdStorage} from "forge-std/Test.sol";

import {ERC20} from "solmate/src/tokens/ERC20.sol";
import {StrikeEthStrategy, ICToken, AffineVault, FixedPointMathLib} from "src/strategies/StrikeEthStrategy.sol";

import {console2} from "forge-std/console2.sol";

contract MockStrikeEthStrategy is StrikeEthStrategy {
constructor(AffineVault _vault, ICToken _cToken, address[] memory strategists)
StrikeEthStrategy(_vault, _cToken, strategists)
{}

function addToPosition(uint256 amount) external {
_afterInvest(amount);
}

function collateral() external returns (uint256) {
return cToken.balanceOfUnderlying(address(this));
}

function debt() external returns (uint256) {
return cToken.balanceOfUnderlying(address(this));
}
}

contract StrikeEthStrategyTest is TestPlus {
using FixedPointMathLib for uint256;

MockStrikeEthStrategy staking;
AffineVault vault;

uint256 depSize = 10 ether;

receive() external payable {}

function setUp() public {
forkEth();

address[] memory strategists = new address[](1);
strategists[0] = address(this);
vault = AffineVault(address(deployL1Vault()));

staking = new MockStrikeEthStrategy(vault, ICToken(0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5), strategists);
vm.prank(governance);
vault.addStrategy(staking, 0);
}

function _giveEther(uint256 amount) internal {
ERC20 weth = staking.WETH();
deal(address(weth), address(staking), amount);
}

function _divest(uint256 amount) internal {
vm.prank(address(vault));
staking.divest(amount);
}

function testAddToPosition() public {
_giveEther(depSize);
staking.addToPosition(depSize);
}

function testLeverage() public {
testAddToPosition();
uint256 collateral = staking.collateral();
assertApproxEqRel(collateral, depSize * staking.leverage() / 100, 0.02e18);
}

function testClosePosition() public {
ERC20 weth = staking.WETH();
testAddToPosition();
vm.warp(block.timestamp + 1 days);
vm.roll(block.number + 1);
_divest(1 ether);
console2.log("WETH balance: %s", weth.balanceOf(address(this)));
console2.log("WETH staking balance: %s", weth.balanceOf(address(staking)));
}

function testTotalLockedValue() public {
testAddToPosition();
uint256 tvl = staking.totalLockedValue();
console2.log("TVL: %s", tvl);
assertApproxEqRel(tvl, depSize, 0.01e18);
}

function testMutateTotalLockedValue() public {
testAddToPosition();
uint256 tvl = staking.totalLockedValue();
console2.log("Orig tvl: ", tvl);
console2.log("orig collateral: ", staking.collateral());
console2.log("orig debt: ", staking.debt());

vm.prank(address(vault));
staking.divest(1 ether);

assertApproxEqRel(staking.totalLockedValue(), tvl - 1 ether, 0.01e18);
}

function testSetParams() public {
staking.setLeverage(1000);
assertEq(staking.leverage(), 1000);
}
}

0 comments on commit 3465627

Please sign in to comment.