Skip to content

Commit

Permalink
update GmxProxyArbitrum (#233)
Browse files Browse the repository at this point in the history
  • Loading branch information
midnight-commit authored May 5, 2024
1 parent efda155 commit 408d099
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 49 deletions.
79 changes: 56 additions & 23 deletions contracts/strategies/arbitrum/gmx/GmxProxyArbitrum.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity 0.8.13;
import "../../../interfaces/IYakStrategy.sol";
import "../../../lib/SafeERC20.sol";
import "../../../lib/DexLibrary.sol";
import "./../../../interfaces/ISimpleRouter.sol";

import "./interfaces/IGmxDepositor.sol";
import "./interfaces/IGmxRewardRouter.sol";
Expand All @@ -30,26 +31,26 @@ contract GmxProxyArbitrum is IGmxProxy {
uint256 internal constant BIPS_DIVISOR = 10000;

address internal constant WETH = 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1;
address internal constant USDC = 0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8;
address internal constant GMX = 0xfc5A1A6EB076a2C7aD06eD22C90d7E710E35ad0a;
address internal constant sGLP = 0x5402B5F40310bDED796c7D0F3FF6683f5C0cFfdf;
address internal constant esGMX = 0xf42Ae1D54fd613C9bb14810b0588FaAa09a426cA;
uint256 internal constant USDG_PRICE_PRECISION = 1e30;

address public devAddr;
address public approvedStrategy;
uint256 public maxEthSwapAmount;
uint256 public minFeeDifference;

IGmxDepositor public immutable override gmxDepositor;
address public immutable override gmxRewardRouter;
address public immutable glpMinter;
ISimpleRouter internal immutable simpleRouter;

address internal immutable gmxRewardTracker;
address internal immutable glpRewardTracker;
address internal immutable glpManager;
address internal immutable vault;
address internal immutable usdg;
address internal immutable wethUsdcPair;
uint256 internal immutable swapFee;

modifier onlyDev() {
require(msg.sender == devAddr, "GmxProxy::onlyDev");
Expand All @@ -65,8 +66,9 @@ contract GmxProxyArbitrum is IGmxProxy {
address _gmxDepositor,
address _gmxRewardRouter,
address _gmxRewardRouterV2,
address _wethUsdcPair,
uint256 _swapFee,
address _simpleRouter,
uint256 _maxEthSwapAmount,
uint256 _minFeeDifference,
address _devAddr
) {
require(_devAddr > address(0), "GmxProxy::Invalid dev address provided");
Expand All @@ -79,8 +81,9 @@ contract GmxProxyArbitrum is IGmxProxy {
glpManager = IGmxRewardRouter(_gmxRewardRouterV2).glpManager();
vault = IGlpManager(glpManager).vault();
usdg = IGmxVault(vault).usdg();
wethUsdcPair = _wethUsdcPair;
swapFee = _swapFee;
simpleRouter = ISimpleRouter(_simpleRouter);
maxEthSwapAmount = _maxEthSwapAmount;
minFeeDifference = _minFeeDifference;
}

function updateDevAddr(address newValue) public onlyDev {
Expand All @@ -93,6 +96,14 @@ contract GmxProxyArbitrum is IGmxProxy {
approvedStrategy = _strategy;
}

function updateMaxEthSwapAmount(uint256 _maxEthSwapAmount) external onlyDev {
maxEthSwapAmount = _maxEthSwapAmount;
}

function updateMinFeeDifference(uint256 _minFeeDifference) external onlyDev {
minFeeDifference = _minFeeDifference;
}

function stakeESGMX() external onlyDev {
gmxDepositor.safeExecute(
gmxRewardRouter,
Expand All @@ -105,32 +116,54 @@ contract GmxProxyArbitrum is IGmxProxy {
return IGmxRewardTracker(gmxRewardTracker).depositBalances(address(gmxDepositor), esGMX);
}

function vaultHasEthCapacity(uint256 _amountIn) internal view returns (bool) {
uint256 price = IGmxVault(vault).getMinPrice(WETH);
function vaultHasCapacity(address _token, uint256 _amountIn) internal view returns (bool) {
uint256 price = IGmxVault(vault).getMinPrice(_token);
uint256 usdgAmount = (_amountIn * price) / USDG_PRICE_PRECISION;
usdgAmount = IGmxVault(vault).adjustForDecimals(usdgAmount, WETH, usdg);
uint256 vaultUsdgAmount = IGmxVault(vault).usdgAmounts(WETH);
uint256 maxUsdgAmount = IGmxVault(vault).maxUsdgAmounts(WETH);
usdgAmount = IGmxVault(vault).adjustForDecimals(usdgAmount, _token, usdg);
uint256 vaultUsdgAmount = IGmxVault(vault).usdgAmounts(_token);
uint256 maxUsdgAmount = IGmxVault(vault).maxUsdgAmounts(_token);
return maxUsdgAmount == 0 || vaultUsdgAmount + usdgAmount < maxUsdgAmount;
}

function swapToUSDC(uint256 _amount) internal returns (uint256) {
return DexLibrary.swap(_amount, WETH, USDC, IPair(wethUsdcPair), swapFee);
}

function buyAndStakeGlp(uint256 _amount) external override onlyStrategy returns (uint256) {
bool sufficientEthCapacity = vaultHasEthCapacity(_amount);
address token = sufficientEthCapacity ? WETH : USDC;
_amount = sufficientEthCapacity ? _amount : swapToUSDC(_amount);

IERC20(token).transfer(address(gmxDepositor), _amount);
address tokenIn = WETH;

if (_amount < maxEthSwapAmount) {
uint256 price = IGmxVault(vault).getMinPrice(WETH);
uint256 usdgAmount = (_amount * price) / USDG_PRICE_PRECISION;
uint256 mintFeeBasisPoints = IGmxVault(vault).mintBurnFeeBasisPoints();
uint256 taxBasisPoints = IGmxVault(vault).taxBasisPoints();
uint256 feeBasisPoints = vaultHasCapacity(WETH, _amount)
? IGmxVault(vault).getFeeBasisPoints(WETH, usdgAmount, mintFeeBasisPoints, taxBasisPoints, true)
: type(uint256).max;

uint256 allWhiteListedTokensLength = IGmxVault(vault).allWhitelistedTokensLength();
for (uint256 i = 0; i < allWhiteListedTokensLength; i++) {
address whitelistedToken = IGmxVault(vault).allWhitelistedTokens(i);
uint256 currentFeeBasisPoints = IGmxVault(vault).getFeeBasisPoints(
whitelistedToken, usdgAmount, mintFeeBasisPoints, taxBasisPoints, true
);
if (currentFeeBasisPoints + minFeeDifference < feeBasisPoints) {
feeBasisPoints = currentFeeBasisPoints;
tokenIn = whitelistedToken;
}
}

if (tokenIn != WETH) {
FormattedOffer memory offer = simpleRouter.query(_amount, WETH, tokenIn);
IERC20(WETH).approve(address(simpleRouter), _amount);
_amount = simpleRouter.swap(offer);
}
}

gmxDepositor.safeExecute(token, 0, abi.encodeWithSignature("approve(address,uint256)", glpManager, _amount));
IERC20(tokenIn).safeTransfer(address(gmxDepositor), _amount);
gmxDepositor.safeExecute(tokenIn, 0, abi.encodeWithSignature("approve(address,uint256)", glpManager, _amount));
bytes memory result = gmxDepositor.safeExecute(
glpMinter,
0,
abi.encodeWithSignature("mintAndStakeGlp(address,uint256,uint256,uint256)", token, _amount, 0, 0)
abi.encodeWithSignature("mintAndStakeGlp(address,uint256,uint256,uint256)", tokenIn, _amount, 0, 0)
);
gmxDepositor.safeExecute(tokenIn, 0, abi.encodeWithSignature("approve(address,uint256)", glpManager, 0));
return toUint256(result, 0);
}

Expand Down
37 changes: 11 additions & 26 deletions contracts/strategies/arbitrum/gmx/interfaces/IGmxVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,19 @@
pragma solidity 0.8.13;

interface IGmxVaultPriceFeed {
function getPrice(
address,
bool,
bool,
bool
) external view returns (uint256);
function getPrice(address, bool, bool, bool) external view returns (uint256);
}

interface IGmxVaultUtils {
function getSwapFeeBasisPoints(
address,
address,
uint256
) external view returns (uint256);
function getSwapFeeBasisPoints(address, address, uint256) external view returns (uint256);

function getBuyUsdgFeeBasisPoints(address _token, uint256 _usdgAmount) external view returns (uint256);

function getSellUsdgFeeBasisPoints(address _token, uint256 _usdgAmount) external view returns (uint256);
}

interface IGmxVault {
function swap(
address,
address,
address
) external;
function swap(address, address, address) external;

function whitelistedTokens(address) external view returns (bool);

Expand Down Expand Up @@ -58,15 +45,17 @@ interface IGmxVault {
function stableTokens(address) external view returns (bool);

function getFeeBasisPoints(
address,
uint256,
uint256,
uint256,
bool
address _token,
uint256 _usdgDelta,
uint256 _feeBasisPoints,
uint256 _taxBasisPoints,
bool _increment
) external view returns (uint256);

function stableSwapFeeBasisPoints() external view returns (uint256);

function mintBurnFeeBasisPoints() external view returns (uint256);

function swapFeeBasisPoints() external view returns (uint256);

function stableTaxBasisPoints() external view returns (uint256);
Expand All @@ -81,11 +70,7 @@ interface IGmxVault {

function getMinPrice(address _token) external view returns (uint256);

function adjustForDecimals(
uint256 _amount,
address _tokenDiv,
address _tokenMul
) external view returns (uint256);
function adjustForDecimals(uint256 _amount, address _tokenDiv, address _tokenMul) external view returns (uint256);

function getRedemptionAmount(address _token, uint256 _usdgAmount) external view returns (uint256);
}

0 comments on commit 408d099

Please sign in to comment.