pragma solidity 0.8.25;
import { CreditDelegationBranch } from "@zaros/market-making/branches/CreditDelegationBranch.sol";
import { VaultRouterBranch } from "@zaros/market-making/branches/VaultRouterBranch.sol";
import { MarketMakingEngineConfigurationBranch } from
"@zaros/market-making/branches/MarketMakingEngineConfigurationBranch.sol";
import { Vault } from "@zaros/market-making/leaves/Vault.sol";
import { Market } from "@zaros/market-making/leaves/Market.sol";
import { CreditDelegation } from "@zaros/market-making/leaves/CreditDelegation.sol";
import { MarketMakingEngineConfiguration } from "@zaros/market-making/leaves/MarketMakingEngineConfiguration.sol";
import { LiveMarkets } from "@zaros/market-making/leaves/LiveMarkets.sol";
import { Collateral } from "@zaros/market-making/leaves/Collateral.sol";
import { UD60x18, ud60x18 } from "@prb-math/UD60x18.sol";
import { SD59x18, sd59x18 } from "@prb-math/SD59x18.sol";
import { Constants } from "@zaros/utils/Constants.sol";
import { SafeCast } from "@openzeppelin/utils/math/SafeCast.sol";
import { EnumerableMap } from "@openzeppelin/utils/structs/EnumerableMap.sol";
import { EnumerableSet } from "@openzeppelin/utils/structs/EnumerableSet.sol";
import { IERC4626 } from "@openzeppelin/token/ERC20/extensions/ERC4626.sol";
import { Errors } from "@zaros/utils/Errors.sol";
import "forge-std/Test.sol";
uint256 constant DEFAULT_DECIMAL = 18;
contract MockVault {
function totalAssets() external pure returns (uint256) {
return 1000 * (10 ** DEFAULT_DECIMAL);
}
}
contract MockPriceAdapter {
function getPrice() external pure returns (uint256) {
return 10 ** DEFAULT_DECIMAL;
}
}
contract MockEngine {
function getUnrealizedDebt(uint128) external pure returns (int256) {
return 0;
}
}
contract MarketMakingConfigurationBranchTest is
CreditDelegationBranch,
VaultRouterBranch,
MarketMakingEngineConfigurationBranch,
Test
{
using Vault for Vault.Data;
using Market for Market.Data;
using CreditDelegation for CreditDelegation.Data;
using Collateral for Collateral.Data;
using SafeCast for uint256;
using EnumerableSet for EnumerableSet.UintSet;
using EnumerableMap for EnumerableMap.AddressToUintMap;
using LiveMarkets for LiveMarkets.Data;
using MarketMakingEngineConfiguration for MarketMakingEngineConfiguration.Data;
uint128 marketId = 1;
uint128 vaultId = 1;
address asset = vm.addr(1);
address usdc = vm.addr(2);
address weth = vm.addr(3);
uint256 collateralAssetAmount = 100 * (10 ** DEFAULT_DECIMAL);
uint256 usdcAmount = 200 * (10 ** DEFAULT_DECIMAL);
uint256 creditRatio = 0.8e18;
uint256[] vaultIds = new uint128[](1);
function setUp() external {
MockVault indexToken = new MockVault();
MockPriceAdapter priceAdapter = new MockPriceAdapter();
MockEngine mockEngine = new MockEngine();
MarketMakingEngineConfiguration.Data storage configuration = MarketMakingEngineConfiguration.load();
configuration.usdc = usdc;
Market.Data storage market = Market.load(marketId);
market.engine = address(mockEngine);
uint256[] memory marketIds = new uint256[](1);
marketIds[0] = uint256(marketId);
vaultIds[0] = uint256(vaultId);
market.id = marketId;
LiveMarkets.Data storage liveMarkets = LiveMarkets.load();
liveMarkets.addMarket(marketId);
Collateral.Data storage collateral = Collateral.load(asset);
collateral.priceAdapter = address(priceAdapter);
collateral.creditRatio = creditRatio;
Vault.Data storage vault = Vault.load(vaultId);
vault.id = vaultId;
vault.indexToken = address(indexToken);
vault.collateral.decimals = uint8(DEFAULT_DECIMAL);
vault.collateral.priceAdapter = address(priceAdapter);
vault.collateral.creditRatio = creditRatio;
uint256[] memory _vaultIds = vaultIds;
_connectVaultsAndMarkets(_vaultIds);
}
function testPoC() external {
Market.Data storage market = Market.load(marketId);
_recalculateVaultsCreditCapacity();
_logStates();
market.depositCredit(asset, ud60x18(collateralAssetAmount));
market.settleCreditDeposit(address(0), ud60x18(100e18));
market.receiveWethReward(weth, ud60x18(0), ud60x18(1e18));
_recalculateVaultsCreditCapacity();
market.settleCreditDeposit(address(0), ud60x18(100e18));
_recalculateVaultsCreditCapacity();
_logStates();
}
function _connectVaultsAndMarkets(uint256[] memory _vaultIds) internal {
uint256[] memory marketIds = new uint256[](1);
marketIds[0] = uint256(marketId);
vm.startPrank(address(0));
MarketMakingConfigurationBranchTest(address(this)).connectVaultsAndMarkets(marketIds, _vaultIds);
vm.stopPrank();
}
function _recalculateVaultsCreditCapacity() internal {
MarketMakingConfigurationBranchTest(address(this)).updateMarketCreditDelegations(marketId);
}
function _logStates() internal {
console.log("\n");
_logMarketState();
_logVaultState();
_logCreditDelegationState();
console.log("\n");
}
function _logMarketState() internal {
Market.Data storage market = Market.load(marketId);
UD60x18 creditDepositsValueUsdX18 = market.getCreditDepositsValueUsd();
SD59x18 marketTotalDebtUsdX18 = market.getTotalDebt();
UD60x18 delegatedCreditUsdX18 = market.getTotalDelegatedCreditUsd();
SD59x18 creditCapacityUsdX18 = Market.getCreditCapacityUsd(delegatedCreditUsdX18, marketTotalDebtUsdX18);
emit log_named_decimal_uint(
"market.creditDepositsValueUsd", creditDepositsValueUsdX18.unwrap(), DEFAULT_DECIMAL
);
emit log_named_decimal_int("market.totalDebtUsd", marketTotalDebtUsdX18.unwrap(), DEFAULT_DECIMAL);
emit log_named_decimal_uint("market.delegatedCreditUsd", delegatedCreditUsdX18.unwrap(), DEFAULT_DECIMAL);
emit log_named_decimal_int("market.creditCapacityUsd", creditCapacityUsdX18.unwrap(), DEFAULT_DECIMAL);
emit log_named_decimal_int(
"market.realizedDebtUsdPerVaultShare", market.realizedDebtUsdPerVaultShare, DEFAULT_DECIMAL
);
emit log_named_decimal_uint(
"market.usdcCreditPerVaultShare", uint256(market.usdcCreditPerVaultShare), DEFAULT_DECIMAL
);
}
function _logVaultState() internal {
Vault.Data storage vault = Vault.load(vaultId);
SD59x18 vaultTotalDebtUsdX18 = vault.getTotalDebt();
SD59x18 vaultTotalCreditCapacityX18 = vault.getTotalCreditCapacityUsd();
emit log_named_decimal_int("vault.totalDebtUsd", vaultTotalDebtUsdX18.unwrap(), DEFAULT_DECIMAL);
emit log_named_decimal_uint("vault.depositedUsdc", uint256(vault.depositedUsdc), DEFAULT_DECIMAL);
emit log_named_decimal_int("vault.totalCreditCapacity", vaultTotalCreditCapacityX18.unwrap(), DEFAULT_DECIMAL);
}
function _logCreditDelegationState() internal {
CreditDelegation.Data storage creditDelegation = CreditDelegation.load(vaultId, uint256(marketId));
emit log_named_decimal_uint("creditDelegation.valueUsd", uint256(creditDelegation.valueUsd), DEFAULT_DECIMAL);
emit log_named_decimal_int(
"creditDelegation.lastVaultDistributedRealizedDebtUsdPerShare",
int256(creditDelegation.lastVaultDistributedRealizedDebtUsdPerShare),
DEFAULT_DECIMAL
);
emit log_named_decimal_uint(
"creditDelegation.lastVaultDistributedUsdcCreditPerShare",
uint256(creditDelegation.lastVaultDistributedUsdcCreditPerShare),
DEFAULT_DECIMAL
);
emit log_named_decimal_uint(
"creditDelegation.lastVaultDistributedUsdcCreditPerShare",
uint256(creditDelegation.lastVaultDistributedWethRewardPerShare),
DEFAULT_DECIMAL
);
}
}
market.creditDepositsValueUsd: 0.000000000000000000
market.totalDebtUsd: 0.000000000000000000
market.delegatedCreditUsd: 800.000000000000000000
market.creditCapacityUsd: 800.000000000000000000
market.realizedDebtUsdPerVaultShare: 0.000000000000000000
market.usdcCreditPerVaultShare: 0.000000000000000000
vault.totalDebtUsd: 0.000000000000000000
vault.depositedUsdc: 0.000000000000000000
vault.totalCreditCapacity: 800.000000000000000000
creditDelegation.valueUsd: 800.000000000000000000
creditDelegation.lastVaultDistributedRealizedDebtUsdPerShare: 0.000000000000000000
creditDelegation.lastVaultDistributedUsdcCreditPerShare: 0.000000000000000000
creditDelegation.lastVaultDistributedUsdcCreditPerShare: 0.000000000000000000
market.creditDepositsValueUsd: 80.000000000000000000
market.totalDebtUsd: 80.000000000000000000
market.delegatedCreditUsd: 800.125000000000000000
market.creditCapacityUsd: 880.125000000000000000
market.realizedDebtUsdPerVaultShare: 0.100000000000000000
market.usdcCreditPerVaultShare: 0.250000000000000000
vault.totalDebtUsd: -0.125000000000000000
vault.depositedUsdc: 0.125000000000000000
vault.totalCreditCapacity: 800.125000000000000000
creditDelegation.valueUsd: 800.125000000000000000
creditDelegation.lastVaultDistributedRealizedDebtUsdPerShare: 0.100000000000000000
creditDelegation.lastVaultDistributedUsdcCreditPerShare: 0.250000000000000000
creditDelegation.lastVaultDistributedUsdcCreditPerShare: 1.000000000000000000
All vault calculation will be disrupted, which in effect will distrupt market calculation.
This will lead to incorrect index token swap rate and usd token swap rate, which will cause user fund loss and protocol's reputation damage.