Skip to content

Commit

Permalink
forge fmt
Browse files Browse the repository at this point in the history
  • Loading branch information
ewansheldon committed Nov 29, 2024
1 parent 5d0f8c0 commit 99775ce
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 68 deletions.
82 changes: 47 additions & 35 deletions contracts/AutoRedemption.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import {IUniswapV3Pool} from "contracts/interfaces/IUniswapV3Pool.sol";
import {IQuoter} from "contracts/interfaces/IQuoter.sol";
import {TickMath} from "src/uniswap/TickMath.sol";
import {LiquidityAmounts} from "src/uniswap/LiquidityAmounts.sol";
import {IERC20} from "lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import {IERC20} from
"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";

contract AutoRedemption is AutomationCompatibleInterface, FunctionsClient, ConfirmedOwner {
using Functions for Functions.Request;
Expand All @@ -31,24 +32,23 @@ contract AutoRedemption is AutomationCompatibleInterface, FunctionsClient, Confi
mapping(address => address) hypervisorCollaterals;
mapping(address => bytes) swapPaths;

string source =
"const { ethers } = await import('npm:[email protected]')"
string source = "const { ethers } = await import('npm:[email protected]')"
"const apiResponse = await Functions.makeHttpRequest({"
"url: 'https://smart-vault-api.thestandard.io/redemption'"
"});"
"if (apiResponse.error) {"
"throw Error('Request failed');"
"}"
"const { data } = apiResponse;"
"const encoded = ethers.AbiCoder.defaultAbiCoder().encode("
"['uint256', 'address', 'uint256'],"
"[data.tokenID, data.collateral, data.value]"
");"
"return ethers.getBytes(encoded);";
"url: 'https://smart-vault-api.thestandard.io/redemption'" "});" "if (apiResponse.error) {"
"throw Error('Request failed');" "}" "const { data } = apiResponse;"
"const encoded = ethers.AbiCoder.defaultAbiCoder().encode(" "['uint256', 'address', 'uint256'],"
"[data.tokenID, data.collateral, data.value]" ");" "return ethers.getBytes(encoded);";

constructor(
address _smartVaultManager, address _functionsRouter, address _pool, address _smartVaultIndex, address _swapRouter,
address _quoter, uint160 _triggerPrice, uint64 _subscriptionID, uint256 _lastLegacyVaultID
address _smartVaultManager,
address _functionsRouter,
address _pool,
address _smartVaultIndex,
address _swapRouter,
address _quoter,
uint160 _triggerPrice,
uint64 _subscriptionID,
uint256 _lastLegacyVaultID
) FunctionsClient(_functionsRouter) ConfirmedOwner(msg.sender) {
smartVaultManager = _smartVaultManager;
swapRouter = _swapRouter;
Expand Down Expand Up @@ -81,21 +81,27 @@ contract AutoRedemption is AutomationCompatibleInterface, FunctionsClient, Confi

function calculateUSDCToTargetPrice() private view returns (uint256 _usdc) {
int24 _spacing = pool.tickSpacing();
(uint160 _sqrtPriceX96,int24 _tick,,,,,) = pool.slot0();
(uint160 _sqrtPriceX96, int24 _tick,,,,,) = pool.slot0();
int24 _upperTick = _tick / _spacing * _spacing;
int24 _lowerTick = _upperTick - _spacing;
uint128 _liquidity = pool.liquidity();
while (TickMath.getSqrtRatioAtTick(_lowerTick) < TARGET_PRICE) {
uint256 _amount0;
if (_tick > _lowerTick && _tick < _upperTick) {
(uint256 _amount0,) = LiquidityAmounts.getAmountsForLiquidity(
_sqrtPriceX96, TickMath.getSqrtRatioAtTick(_lowerTick), TickMath.getSqrtRatioAtTick(_upperTick), _liquidity
(uint256 _amount0,) = LiquidityAmounts.getAmountsForLiquidity(
_sqrtPriceX96,
TickMath.getSqrtRatioAtTick(_lowerTick),
TickMath.getSqrtRatioAtTick(_upperTick),
_liquidity
);
} else {
(,int128 _liquidityNet,,,,,,) = pool.ticks(_lowerTick);
(, int128 _liquidityNet,,,,,,) = pool.ticks(_lowerTick);
_liquidity += uint128(_liquidityNet);
(uint256 _amount0,) = LiquidityAmounts.getAmountsForLiquidity(
_sqrtPriceX96, TickMath.getSqrtRatioAtTick(_lowerTick), TickMath.getSqrtRatioAtTick(_upperTick), _liquidity
(uint256 _amount0,) = LiquidityAmounts.getAmountsForLiquidity(
_sqrtPriceX96,
TickMath.getSqrtRatioAtTick(_lowerTick),
TickMath.getSqrtRatioAtTick(_upperTick),
_liquidity
);
}
_usdc += _amount0;
Expand All @@ -104,36 +110,42 @@ contract AutoRedemption is AutomationCompatibleInterface, FunctionsClient, Confi
}
}

function legacyAutoRedemption(address _smartVault, address _token, bytes memory _collateralToUSDCPath, uint256 _USDCTargetAmount, uint256 _estimatedCollateralValueUSD) private {
uint256 _collateralBalance = _token == address(0) ?
_smartVault.balance :
IERC20(_token).balanceOf(_smartVault);
(uint256 _approxAmountInRequired,,,) = IQuoter(quoter).quoteExactOutput(_collateralToUSDCPath, _USDCTargetAmount);
function legacyAutoRedemption(
address _smartVault,
address _token,
bytes memory _collateralToUSDCPath,
uint256 _USDCTargetAmount,
uint256 _estimatedCollateralValueUSD
) private {
uint256 _collateralBalance = _token == address(0) ? _smartVault.balance : IERC20(_token).balanceOf(_smartVault);
(uint256 _approxAmountInRequired,,,) =
IQuoter(quoter).quoteExactOutput(_collateralToUSDCPath, _USDCTargetAmount);
uint256 _amountIn = _approxAmountInRequired > _collateralBalance ? _collateralBalance : _approxAmountInRequired;
IRedeemableLegacy(_smartVault).autoRedemption(swapRouter, _token, _collateralToUSDCPath, _amountIn);
}

function fulfillRequest(
bytes32 requestId,
bytes memory response,
bytes memory err
) internal override {
function fulfillRequest(bytes32 requestId, bytes memory response, bytes memory err) internal override {
// TODO proper error handling
// if (err) revert;
if (requestId != lastRequestId) revert("wrong request");
uint256 _USDCTargetAmount = calculateUSDCToTargetPrice();
(uint256 _tokenID, address _token, uint256 _estimatedCollateralValueUSD) = abi.decode(response,(uint256,address,uint256));
(uint256 _tokenID, address _token, uint256 _estimatedCollateralValueUSD) =
abi.decode(response, (uint256, address, uint256));
bytes memory _collateralToUSDCPath = swapPaths[_token];
address _smartVault = ISmartVaultIndex(smartVaultIndex).getVaultAddress(_tokenID);
if (_tokenID <= lastLegacyVaultID) {
legacyAutoRedemption(_smartVault, _token, _collateralToUSDCPath, _USDCTargetAmount, _estimatedCollateralValueUSD);
legacyAutoRedemption(
_smartVault, _token, _collateralToUSDCPath, _USDCTargetAmount, _estimatedCollateralValueUSD
);
} else {
address _hypervisor;
if (hypervisorCollaterals[_token] != address(0)) {
_hypervisor = _token;
_token = hypervisorCollaterals[_hypervisor];
}
IRedeemable(_smartVault).autoRedemption(swapRouter, quoter, _token, _collateralToUSDCPath, _USDCTargetAmount, _hypervisor);
IRedeemable(_smartVault).autoRedemption(
swapRouter, quoter, _token, _collateralToUSDCPath, _USDCTargetAmount, _hypervisor
);
}
lastRequestId = bytes32(0);
}
Expand Down
46 changes: 30 additions & 16 deletions contracts/SmartVaultV4.sol
Original file line number Diff line number Diff line change
Expand Up @@ -292,11 +292,15 @@ contract SmartVaultV4 is ISmartVault, IRedeemable {
}
}

function calculateAmountIn(address _quoterAddress, address _collateralToken, bytes memory _swapPath, uint256 _USDCTargetAmount) private returns (uint256) {
function calculateAmountIn(
address _quoterAddress,
address _collateralToken,
bytes memory _swapPath,
uint256 _USDCTargetAmount
) private returns (uint256) {
(uint256 _quoteAmountIn,,,) = IQuoter(_quoterAddress).quoteExactOutput(_swapPath, _USDCTargetAmount);
uint256 _collateralBalance = getAssetBalance(_collateralToken);
return _quoteAmountIn > _collateralBalance ?
_collateralBalance : _quoteAmountIn;
return _quoteAmountIn > _collateralBalance ? _collateralBalance : _quoteAmountIn;
}

function swapCollateral(
Expand All @@ -308,21 +312,25 @@ contract SmartVaultV4 is ISmartVault, IRedeemable {
) private {
uint256 _amountIn = calculateAmountIn(_quoterAddress, _collateralToken, _swapPath, _USDCTargetAmount);
IERC20(_collateralToken).safeIncreaseAllowance(_swapRouterAddress, _amountIn);
ISwapRouter(_swapRouterAddress).exactInput(ISwapRouter.ExactInputParams({
path: _swapPath,
recipient: address(this),
deadline: block.timestamp,
amountIn: _amountIn,
// minimum USD value of collateral out from swap
amountOutMinimum: calculator.tokenToUSD(
ITokenManager(ISmartVaultManagerV3(manager).tokenManager()).getTokenIfExists(_collateralToken),
_amountIn
)
}));
ISwapRouter(_swapRouterAddress).exactInput(
ISwapRouter.ExactInputParams({
path: _swapPath,
recipient: address(this),
deadline: block.timestamp,
amountIn: _amountIn,
// minimum USD value of collateral out from swap
amountOutMinimum: calculator.tokenToUSD(
ITokenManager(ISmartVaultManagerV3(manager).tokenManager()).getTokenIfExists(_collateralToken),
_amountIn
)
})
);
IERC20(_collateralToken).forceApprove(_swapRouterAddress, 0);
}

function redeposit(uint256 _withdrawn, uint256 _collateralBalance, address _hypervisor, address _collateralToken) private {
function redeposit(uint256 _withdrawn, uint256 _collateralBalance, address _hypervisor, address _collateralToken)
private
{
uint256 _redeposit = _withdrawn > _collateralBalance ? _collateralBalance : _withdrawn;
address _yieldManager = ISmartVaultManagerV3(manager).yieldManager();
IERC20(_collateralToken).safeIncreaseAllowance(_yieldManager, _redeposit);
Expand Down Expand Up @@ -429,7 +437,13 @@ contract SmartVaultV4 is ISmartVault, IRedeemable {
) revert Undercollateralised();
}

function merklClaim(address _distributor, address[] calldata users, address[] calldata tokens, uint256[] calldata amounts, bytes32[][] calldata proofs) external onlyOwner {
function merklClaim(
address _distributor,
address[] calldata users,
address[] calldata tokens,
uint256[] calldata amounts,
bytes32[][] calldata proofs
) external onlyOwner {
IMerklDistributor(_distributor).claim(users, tokens, amounts, proofs);
}

Expand Down
8 changes: 7 additions & 1 deletion contracts/SmartVaultV4Legacy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,13 @@ contract SmartVaultV4Legacy is ISmartVault, IRedeemableLegacy {
) revert Undercollateralised();
}

function merklClaim(address _distributor, address[] calldata users, address[] calldata tokens, uint256[] calldata amounts, bytes32[][] calldata proofs) external onlyOwner {
function merklClaim(
address _distributor,
address[] calldata users,
address[] calldata tokens,
uint256[] calldata amounts,
bytes32[][] calldata proofs
) external onlyOwner {
IMerklDistributor(_distributor).claim(users, tokens, amounts, proofs);
}

Expand Down
4 changes: 1 addition & 3 deletions contracts/SmartVaultYieldManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -324,9 +324,7 @@ contract SmartVaultYieldManager is ISmartVaultYieldManager, Ownable {
_otherDeposit(_collateralToken, _hypervisorData);
}

function quickWithdraw(address _hypervisor, address _token) external returns (uint256 _withdrawn) {

}
function quickWithdraw(address _hypervisor, address _token) external returns (uint256 _withdrawn) {}

function addHypervisorData(
address _collateralToken,
Expand Down
7 changes: 6 additions & 1 deletion contracts/interfaces/IMerklDistributor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,10 @@
pragma solidity 0.8.21;

interface IMerklDistributor {
function claim(address[] calldata users, address[] calldata tokens, uint256[] calldata amounts, bytes32[][] calldata proofs) external;
function claim(
address[] calldata users,
address[] calldata tokens,
uint256[] calldata amounts,
bytes32[][] calldata proofs
) external;
}
2 changes: 1 addition & 1 deletion contracts/interfaces/IQuoter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,4 @@ interface IQuoter {
uint32[] memory initializedTicksCrossedList,
uint256 gasEstimate
);
}
}
25 changes: 14 additions & 11 deletions contracts/interfaces/IUniswapV3Pool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,18 @@ interface IUniswapV3Pool {
function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external;

function liquidity() external view returns (uint128);

function ticks(int24 tick) external view returns (
uint128 liquidityGross,
int128 liquidityNet,
uint256 feeGrowthOutside0X128,
uint256 feeGrowthOutside1X128,
int56 tickCumulativeOutside,
uint160 secondsPerLiquidityOutsideX128,
uint32 secondsOutside,
bool initialized
);

function ticks(int24 tick)
external
view
returns (
uint128 liquidityGross,
int128 liquidityNet,
uint256 feeGrowthOutside0X128,
uint256 feeGrowthOutside1X128,
int56 tickCumulativeOutside,
uint160 secondsPerLiquidityOutsideX128,
uint32 secondsOutside,
bool initialized
);
}

0 comments on commit 99775ce

Please sign in to comment.