Skip to content

Commit

Permalink
Passing mint test for Mellow adaptor
Browse files Browse the repository at this point in the history
  • Loading branch information
otsalex committed Nov 21, 2024
1 parent e1de966 commit 741c5a2
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 24 deletions.
4 changes: 1 addition & 3 deletions src/interfaces/external/IStaking.sol
Original file line number Diff line number Diff line change
Expand Up @@ -194,15 +194,13 @@ interface IVault is IERC20 {
/// @param amounts An array specifying the amounts for each underlying token.
/// @param minLpAmount The minimum amount of LP tokens to mint.
/// @param deadline The time before which the operation must be completed.
/// @param referralCode The referral code to use for the deposit.
/// @return actualAmounts The actual amounts deposited for each underlying token.
/// @return lpAmount The amount of LP tokens minted.
function deposit(
address to,
uint256[] memory amounts,
uint256 minLpAmount,
uint256 deadline,
uint256 referralCode
uint256 deadline
) external returns (uint256[] memory actualAmounts, uint256 lpAmount);

/// @notice Handles emergency withdrawals, proportionally withdrawing all tokens in the system (not just the underlying).
Expand Down
18 changes: 12 additions & 6 deletions src/modules/adaptors/Staking/MellowStakingAdaptor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,16 @@ import { IVault } from "src/interfaces/external/IStaking.sol";
*/
ERC20 public immutable vaultToken;


ERC20 public immutable baseAsset;

constructor(
address _baseAsset,
uint8 _maxRequests,
address _mellowVault,
address _vaultToken
) StakingAdaptor(_baseAsset, _maxRequests) {
baseAsset = ERC20(_baseAsset);
mellowVault = IVault(_mellowVault);
vaultToken = ERC20(_vaultToken);
}
Expand All @@ -53,25 +57,27 @@ import { IVault } from "src/interfaces/external/IStaking.sol";
* @dev Deposit funds into the Mellow staking contract.
* @param _amount The amount of funds to deposit.
*/
function mint(uint256 _amount, uint256 minAmountOut, bytes calldata) external override {
vaultToken.safeTransferFrom(msg.sender, address(this), _amount);
vaultToken.safeApprove(address(mellowVault), _amount);
function _mintERC20(ERC20, uint256 _amount, uint256, bytes calldata) internal override returns (uint256 shares) {

baseAsset.safeApprove(address(vaultToken), _amount);

uint256[] memory amounts = new uint256[](1);
amounts[0] = _amount;
mellowVault.deposit(address(this), amounts, 0, type(uint256).max, 0);
(,uint256 shares) = mellowVault.deposit(address(this), amounts, 0, type(uint256).max);
}

/**
* @dev Withdraw funds from the Mellow staking contract.
* @param _amount The amount of funds to withdraw.
*/
function requestBurn(uint256 _amount, bytes calldata wildcard) external override {
function _requestBurn(uint256 _amount, bytes calldata) internal override returns (uint256) {
uint256[] memory min_amounts = new uint256[](1);
min_amounts[0] = 0;
mellowVault.registerWithdrawal(address(this),_amount, min_amounts, type(uint256).max, type(uint256).max, false);
return 0;
}

function cancelWithdrawalRequest() internal {
function _cancelBurn(uint256, bytes calldata) internal override {
mellowVault.cancelWithdrawalRequest();
}
}
40 changes: 25 additions & 15 deletions test/testAdaptors/StakingAdaptors/MellowStakingAdaptor.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { Cellar } from "src/base/Cellar.sol";
// Import Everything from Starter file.
import "test/resources/MainnetStarter.t.sol";

import "forge-std/console.sol";

import { AdaptorHelperFunctions } from "test/resources/AdaptorHelperFunctions.sol";

contract MellowStakingAdaptorTest is MainnetStarterTest, AdaptorHelperFunctions {
Expand All @@ -17,13 +19,15 @@ contract MellowStakingAdaptorTest is MainnetStarterTest, AdaptorHelperFunctions
MellowStakingAdaptor private mellowAdaptor;
Cellar private cellar;

uint32 public wethPosition = 1;
uint32 public wstethPosition = 1;
uint32 public rstETHPosition = 2;

ERC20 public rstETH = ERC20(0x7a4EffD87C2f3C55CA251080b1343b605f327E3a);
address public mellowVault = 0xaf108ae0AD8700ac41346aCb620e828c03BB8848;

ERC20 public primitive = WETH;
address public WSTETH_USD_FEED = 0x164b276057258d81941e97B0a900D4C7B358bCe0;

ERC20 public primitive = WSTETH;
ERC20 public derivative = rstETH;
ERC20 public wrappedDerivative = ERC20(address(0));

Expand All @@ -40,26 +44,26 @@ contract MellowStakingAdaptorTest is MainnetStarterTest, AdaptorHelperFunctions
// Run Starter setUp code.
_setUp();

mellowAdaptor = new MellowStakingAdaptor(address(WETH), 8, mellowVault, address(rstETH));
mellowAdaptor = new MellowStakingAdaptor(address(primitive), 8, address(rstETH), address(rstETH));

PriceRouter.ChainlinkDerivativeStorage memory stor;

PriceRouter.AssetSettings memory settings;

uint256 price = uint256(IChainlinkAggregator(WETH_USD_FEED).latestAnswer());
settings = PriceRouter.AssetSettings(CHAINLINK_DERIVATIVE, WETH_USD_FEED);
priceRouter.addAsset(WETH, settings, abi.encode(stor), price);
uint256 price = uint256(IChainlinkAggregator(WSTETH_USD_FEED).latestAnswer());
settings = PriceRouter.AssetSettings(CHAINLINK_DERIVATIVE, WSTETH_USD_FEED);
priceRouter.addAsset(WSTETH, settings, abi.encode(stor), price);

// Set rstETH to be 1:1 with ETH.
price = uint256(IChainlinkAggregator(WETH_USD_FEED).latestAnswer());
settings = PriceRouter.AssetSettings(CHAINLINK_DERIVATIVE, WETH_USD_FEED);
// Set rstETH to be 1:1 with WSTETH.
price = uint256(IChainlinkAggregator(WSTETH_USD_FEED).latestAnswer());
settings = PriceRouter.AssetSettings(CHAINLINK_DERIVATIVE, WSTETH_USD_FEED);
priceRouter.addAsset(rstETH, settings, abi.encode(stor), price);
// Setup Cellar:

// Add adaptors and positions to the registry.
registry.trustAdaptor(address(mellowAdaptor));

registry.trustPosition(wethPosition, address(erc20Adaptor), abi.encode(WETH));
registry.trustPosition(wstethPosition, address(erc20Adaptor), abi.encode(WSTETH));
registry.trustPosition(rstETHPosition, address(erc20Adaptor), abi.encode(rstETH));

string memory cellarName = "Mellow Cellar V0.0";
Expand All @@ -68,8 +72,8 @@ contract MellowStakingAdaptorTest is MainnetStarterTest, AdaptorHelperFunctions

cellar = _createCellarLocal(
cellarName,
WETH,
wethPosition,
WSTETH,
wstethPosition,
abi.encode(true),
initialDeposit,
platformCut
Expand All @@ -84,12 +88,13 @@ contract MellowStakingAdaptorTest is MainnetStarterTest, AdaptorHelperFunctions

initialAssets = initialDeposit;

WETH.safeApprove(address(cellar), type(uint256).max);
WSTETH.safeApprove(address(cellar), type(uint256).max);
}

function testMint(uint256 mintAmount) external {
mintAmount = bound(mintAmount, 0.0001e18, 10e18);
deal(address(primitive), address(this), mintAmount);

cellar.deposit(mintAmount, address(this));
// Rebalance Cellar to mint derivative.
_mintDerivative(mintAmount, 0);
Expand All @@ -100,8 +105,10 @@ contract MellowStakingAdaptorTest is MainnetStarterTest, AdaptorHelperFunctions
"Should only have initialAssets of primitive left."
);
uint256 expectedDerivativeAmount = priceRouter.getValue(primitive, mintAmount, derivative);
uint256 res = derivative.balanceOf(address(cellar));

assertApproxEqRel(
derivative.balanceOf(address(cellar)),
res,
expectedDerivativeAmount,
0.01e18,
"Should have minted wrapped derivative with mintAmount."
Expand Down Expand Up @@ -130,10 +137,13 @@ contract MellowStakingAdaptorTest is MainnetStarterTest, AdaptorHelperFunctions
// Rebalance Cellar to mint derivative.
Cellar.AdaptorCall[] memory data = new Cellar.AdaptorCall[](1);
bytes[] memory adaptorCalls = new bytes[](1);
adaptorCalls[0] = _createBytesDataToMint(mintAmount, minAmountOut, hex"");

adaptorCalls[0] = _createBytesDataToMintERC20(WSTETH, mintAmount, minAmountOut, hex"");

data[0] = Cellar.AdaptorCall({ adaptor: address(mellowAdaptor), callData: adaptorCalls });

cellar.callOnAdaptor(data);

}

function _createCellarLocal(
Expand Down

0 comments on commit 741c5a2

Please sign in to comment.