Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions contracts/pools/VaultGammaPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ contract VaultGammaPool is CPMMGammaPool, IVaultGammaPool {

/// @dev See {IVaultGammaPool-getReservedBalances}
function getReservedBalances() external virtual override view returns(uint256, uint256) {
return(s.getUint256(uint256(IVaultGammaPool.StorageIndexes.RESERVED_BORROWED_INVARIANT)),
s.getUint256(uint256(IVaultGammaPool.StorageIndexes.RESERVED_LP_TOKENS)));
return(s.getUint256(RESERVED_BORROWED_INVARIANT()), s.getUint256(RESERVED_LP_TOKENS()));
}

/// @dev See {IGammaPoolExternal-liquidateExternally}
Expand All @@ -43,7 +42,7 @@ contract VaultGammaPool is CPMMGammaPool, IVaultGammaPool {
/// @dev See {GammaPoolERC4626-maxAssets}
function maxAssets(uint256 assets) internal view virtual override returns(uint256) {
uint256 lpTokenBalance = s.LP_TOKEN_BALANCE; // CFMM LP tokens in GammaPool that have not been borrowed
lpTokenBalance = lpTokenBalance - GSMath.min(s.getUint256(uint256(IVaultGammaPool.StorageIndexes.RESERVED_LP_TOKENS)), lpTokenBalance);
lpTokenBalance = lpTokenBalance - GSMath.min(s.getUint256(RESERVED_LP_TOKENS()), lpTokenBalance);
if(assets < lpTokenBalance){ // limit assets available to withdraw to what has not been borrowed
return assets;
}
Expand All @@ -59,7 +58,7 @@ contract VaultGammaPool is CPMMGammaPool, IVaultGammaPool {
pool: address(this),
paramsStore: _factory,
BORROWED_INVARIANT: s.BORROWED_INVARIANT,
RESERVED_BORROWED_INVARIANT: s.getUint256(uint256(IVaultGammaPool.StorageIndexes.RESERVED_BORROWED_INVARIANT)),
RESERVED_BORROWED_INVARIANT: s.getUint256(RESERVED_BORROWED_INVARIANT()),
latestCfmmInvariant: _getLatestCFMMInvariant(),
latestCfmmTotalSupply: _getLatestCFMMTotalSupply(),
LAST_BLOCK_NUMBER: s.LAST_BLOCK_NUMBER,
Expand All @@ -72,4 +71,12 @@ contract VaultGammaPool is CPMMGammaPool, IVaultGammaPool {
})
);
}

function RESERVED_LP_TOKENS() internal virtual pure returns(uint256) {
return uint256(0x1d4997f9934f878df7106acada1ff771325c95fb5c98472c2bbed4497048bf65);
}

function RESERVED_BORROWED_INVARIANT() internal virtual pure returns(uint256) {
return uint256(0x54f559f312bc80877ff037529d330829149d3630a04e9d467f30196e91b6ad9d);
}
}
5 changes: 3 additions & 2 deletions contracts/strategies/vault/base/VaultBaseRepayStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,13 @@ abstract contract VaultBaseRepayStrategy is BaseRepayStrategy, VaultBaseRebalanc
}

if(_loan.refType == 3 && _paidLiquidity > 0) {
uint256 reservedBorrowedInvariant = s.getUint256(uint256(IVaultGammaPool.StorageIndexes.RESERVED_BORROWED_INVARIANT));
uint256 key = RESERVED_BORROWED_INVARIANT();
uint256 reservedBorrowedInvariant = s.getUint256(key);
_paidLiquidity = GSMath.min(reservedBorrowedInvariant, _paidLiquidity);
unchecked {
reservedBorrowedInvariant = reservedBorrowedInvariant - _paidLiquidity;
}
s.setUint256(uint256(IVaultGammaPool.StorageIndexes.RESERVED_BORROWED_INVARIANT), reservedBorrowedInvariant);
s.setUint256(key, reservedBorrowedInvariant);
}
}
}
16 changes: 11 additions & 5 deletions contracts/strategies/vault/base/VaultBaseStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ abstract contract VaultBaseStrategy is BaseStrategy {
/// @param lastFeeIndex - interest accrued to loans in GammaPool
/// @return newBorrowedInvariant - borrowed invariant with accrued interest
function accrueBorrowedInvariant(uint256 borrowedInvariant, uint256 lastFeeIndex) internal virtual override view returns(uint256) {
uint256 reservedBorrowedInvariant = s.getUint256(uint256(IVaultGammaPool.StorageIndexes.RESERVED_BORROWED_INVARIANT));
reservedBorrowedInvariant = GSMath.min(borrowedInvariant,reservedBorrowedInvariant);
uint256 reservedBorrowedInvariant = GSMath.min(borrowedInvariant,s.getUint256(RESERVED_BORROWED_INVARIANT()));
unchecked {
borrowedInvariant = borrowedInvariant - reservedBorrowedInvariant;
}
Expand All @@ -39,9 +38,8 @@ abstract contract VaultBaseStrategy is BaseStrategy {
function checkExpectedUtilizationRate(uint256 lpTokens, bool isLoan) internal virtual override view {
uint256 lastCFMMInvariant = s.lastCFMMInvariant;
uint256 lastCFMMTotalSupply = s.lastCFMMTotalSupply;
uint256 reservedLPTokens = s.getUint256(uint256(IVaultGammaPool.StorageIndexes.RESERVED_LP_TOKENS));

uint256 reservedLPInvariant = convertLPToInvariant(reservedLPTokens, lastCFMMInvariant, lastCFMMTotalSupply);
uint256 reservedLPInvariant = convertLPToInvariant(s.getUint256(RESERVED_LP_TOKENS()), lastCFMMInvariant, lastCFMMTotalSupply);
uint256 lpTokenInvariant = convertLPToInvariant(lpTokens, lastCFMMInvariant, lastCFMMTotalSupply);
uint256 lpInvariant = s.LP_INVARIANT;
lpInvariant = lpInvariant >= reservedLPInvariant ? lpInvariant - reservedLPInvariant : 0;
Expand All @@ -57,11 +55,19 @@ abstract contract VaultBaseStrategy is BaseStrategy {
}

function getAdjLPTokenBalance() internal virtual view returns(uint256 lpTokenBalance) {
uint256 reservedLPTokens = s.getUint256(uint256(IVaultGammaPool.StorageIndexes.RESERVED_LP_TOKENS));
uint256 reservedLPTokens = s.getUint256(RESERVED_LP_TOKENS());
lpTokenBalance = s.LP_TOKEN_BALANCE;
reservedLPTokens = GSMath.min(lpTokenBalance, reservedLPTokens);
unchecked {
lpTokenBalance = lpTokenBalance - reservedLPTokens;
}
}

function RESERVED_LP_TOKENS() internal virtual pure returns(uint256) {
return uint256(0x1d4997f9934f878df7106acada1ff771325c95fb5c98472c2bbed4497048bf65);
}

function RESERVED_BORROWED_INVARIANT() internal virtual pure returns(uint256) {
return uint256(0x54f559f312bc80877ff037529d330829149d3630a04e9d467f30196e91b6ad9d);
}
}
12 changes: 6 additions & 6 deletions contracts/strategies/vault/lending/VaultBorrowStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ contract VaultBorrowStrategy is VaultBaseRebalanceStrategy, BorrowStrategy {
uint256 lpInvariant = s.LP_INVARIANT;
uint256 reservedLPInvariant = 0;
if(!isRefType3) {
reservedLPInvariant = convertLPToInvariant(s.getUint256(uint256(IVaultGammaPool.StorageIndexes.RESERVED_LP_TOKENS)),
lastCFMMInvariant, lastCFMMTotalSupply);
reservedLPInvariant = convertLPToInvariant(s.getUint256(RESERVED_LP_TOKENS()), lastCFMMInvariant, lastCFMMTotalSupply);
reservedLPInvariant = GSMath.min(lpInvariant, reservedLPInvariant);
unchecked {
lpInvariant = lpInvariant - reservedLPInvariant;
Expand Down Expand Up @@ -85,11 +84,12 @@ contract VaultBorrowStrategy is VaultBaseRebalanceStrategy, BorrowStrategy {
checkExpectedUtilizationRate(lpTokens, isRefType3);

if(isRefType3) {
uint256 reservedLPTokens = s.getUint256(uint256(IVaultGammaPool.StorageIndexes.RESERVED_LP_TOKENS));
uint256 key = RESERVED_LP_TOKENS();
uint256 reservedLPTokens = s.getUint256(key);
unchecked {
reservedLPTokens = reservedLPTokens - GSMath.min(reservedLPTokens, lpTokens);
}
s.setUint256(uint256(IVaultGammaPool.StorageIndexes.RESERVED_LP_TOKENS), reservedLPTokens);
s.setUint256(key, reservedLPTokens);
}

// Withdraw reserve tokens from CFMM that lpTokens represent
Expand All @@ -102,8 +102,8 @@ contract VaultBorrowStrategy is VaultBaseRebalanceStrategy, BorrowStrategy {
(liquidityBorrowed, loanLiquidity) = openLoan(_loan, lpTokens);

if(isRefType3) {
uint256 reservedBorrowedInvariant = s.getUint256(uint256(IVaultGammaPool.StorageIndexes.RESERVED_BORROWED_INVARIANT));
s.setUint256(uint256(IVaultGammaPool.StorageIndexes.RESERVED_BORROWED_INVARIANT), reservedBorrowedInvariant + liquidityBorrowed);
uint256 key = RESERVED_BORROWED_INVARIANT();
s.setUint256(key, s.getUint256(key) + liquidityBorrowed);
}

if(isRatioValid(ratio)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ contract VaultExternalRebalanceStrategy is VaultBaseLongStrategy, ExternalRebala

updateLoan(_loan);

uint256 key = RESERVED_LP_TOKENS();
if(isReserve) {
uint256 lpTokenBalance = getAdjLPTokenBalance();

Expand All @@ -58,18 +59,16 @@ contract VaultExternalRebalanceStrategy is VaultBaseLongStrategy, ExternalRebala

checkExpectedUtilizationRate(lpTokens, true);

uint256 reservedLPTokens = s.getUint256(uint256(IVaultGammaPool.StorageIndexes.RESERVED_LP_TOKENS));

s.setUint256(uint256(IVaultGammaPool.StorageIndexes.RESERVED_LP_TOKENS), reservedLPTokens + lpTokens);
s.setUint256(key, s.getUint256(key) + lpTokens);
} else {
uint256 reservedLPTokens = s.getUint256(uint256(IVaultGammaPool.StorageIndexes.RESERVED_LP_TOKENS));
uint256 reservedLPTokens = s.getUint256(key);

lpTokens = GSMath.min(reservedLPTokens, lpTokens);
unchecked {
reservedLPTokens = reservedLPTokens - lpTokens;
}

s.setUint256(uint256(IVaultGammaPool.StorageIndexes.RESERVED_LP_TOKENS), reservedLPTokens);
s.setUint256(key, reservedLPTokens);
}

return lpTokens;
Expand Down
24 changes: 24 additions & 0 deletions contracts/test/TestVaultGammaPool.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
pragma solidity ^0.8.0;

import "../pools/VaultGammaPool.sol";

contract TestVaultGammaPool is VaultGammaPool {
constructor(InitializationParams memory params) VaultGammaPool(params) {
}

function getRESERVED_LP_TOKENS() external virtual pure returns(uint256) {
return RESERVED_LP_TOKENS();
}

function getRESERVED_BORROWED_INVARIANT() external virtual pure returns(uint256) {
return RESERVED_BORROWED_INVARIANT();
}

function reserveLPTokens(uint256 tokenId, uint256 lpTokens, bool isReserve) external virtual override returns(uint256) {
return 0;
}

function validateCFMM(address[] calldata _tokens, address _cfmm, bytes calldata) external virtual override view returns(address[] memory) {
return new address[](0);
}
}
58 changes: 58 additions & 0 deletions contracts/test/strategies/vault/TestVaultBaseStrategy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;

import "../../../strategies/vault/base/VaultBaseStrategy.sol";

contract TestVaultBaseStrategy is VaultBaseStrategy {

constructor() {
}

function getRESERVED_LP_TOKENS() external virtual pure returns(uint256) {
return RESERVED_LP_TOKENS();
}

function getRESERVED_BORROWED_INVARIANT() external virtual pure returns(uint256) {
return RESERVED_BORROWED_INVARIANT();
}

function calcBorrowRate(uint256 lpInvariant, uint256 borrowedInvariant, address paramsStore, address pool) public
virtual override view returns(uint256, uint256, uint256, uint256) {
return (0,0,0,0);
}

function validateParameters(bytes calldata _data) external virtual override view returns(bool) {
return false;
}

function syncCFMM(address cfmm) internal virtual override {
}

function getReserves(address cfmm) internal virtual override view returns(uint128[] memory) {
return new uint128[](0);
}

function getLPReserves(address cfmm, bool isLatest) internal virtual override view returns(uint128[] memory) {
return new uint128[](0);
}

function calcInvariant(address cfmm, uint128[] memory amounts) internal virtual override view returns(uint256) {
return 0;
}

function depositToCFMM(address cfmm, address to, uint256[] memory amounts) internal virtual override returns(uint256) {
return 0;
}

function withdrawFromCFMM(address cfmm, address to, uint256 lpTokens) internal virtual override returns(uint256[] memory) {
return new uint256[](0);
}

function maxTotalApy() internal virtual override view returns(uint256) {
return 0;
}

function blocksPerYear() internal virtual override view returns(uint256) {
return 0;
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@gammaswap/v1-implementations",
"version": "1.2.16",
"version": "1.2.17",
"description": "Pool and strategies implementation contracts for GammaSwap V1 protocol",
"homepage": "https://gammaswap.com",
"scripts": {
Expand Down
48 changes: 48 additions & 0 deletions test/foundry/VaultGammaPool.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
pragma solidity ^0.8.0;

import "forge-std/Test.sol";
import "../../contracts/test/TestVaultGammaPool.sol";
import "../../contracts/test/strategies/vault/TestVaultBaseStrategy.sol";

contract VaultGammaPoolTest is Test {

TestVaultGammaPool vaultPool;
TestVaultBaseStrategy vaultStrategy;

function setUp() public {
ICPMMGammaPool.InitializationParams memory params = ICPMMGammaPool.InitializationParams({
protocolId: 1,
factory: address(0),
borrowStrategy: address(0),
repayStrategy: address(0),
rebalanceStrategy: address(0),
shortStrategy: address(0),
liquidationStrategy: address(0),
batchLiquidationStrategy: address(0),
viewer: address(0),
externalRebalanceStrategy: address(0),
externalLiquidationStrategy: address(0),
cfmmFactory: address(0),
cfmmInitCodeHash: bytes32(0)
});

vaultPool = new TestVaultGammaPool(params);
vaultStrategy = new TestVaultBaseStrategy();
}

function testPoolRESERVED_BORROWED_INVARIANT() public {
assertEq(vaultPool.getRESERVED_BORROWED_INVARIANT(),uint256(keccak256("RESERVED_BORROWED_INVARIANT")));
}

function testPoolRESERVED_LP_TOKENS() public {
assertEq(vaultPool.getRESERVED_LP_TOKENS(),uint256(keccak256("RESERVED_LP_TOKENS")));
}

function testStrategyRESERVED_BORROWED_INVARIANT() public {
assertEq(vaultStrategy.getRESERVED_BORROWED_INVARIANT(),uint256(keccak256("RESERVED_BORROWED_INVARIANT")));
}

function testStrategyRESERVED_LP_TOKENS() public {
assertEq(vaultStrategy.getRESERVED_LP_TOKENS(),uint256(keccak256("RESERVED_LP_TOKENS")));
}
}
Loading