@usdu-core/usdu-core 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +12 -0
- package/.env.example +6 -0
- package/.prettierrc.json +7 -0
- package/LICENSE +674 -0
- package/README.md +244 -0
- package/contracts/curve/CurveAdapterV1.sol +310 -0
- package/contracts/curve/CurveAdapterV1_1.sol +198 -0
- package/contracts/curve/helpers/ICurveStableSwapNG.json +566 -0
- package/contracts/curve/helpers/ICurveStableSwapNG.sol +177 -0
- package/contracts/deploy/VaultDeployer.sol +110 -0
- package/contracts/morpho/MorphoAdapterV1.sol +255 -0
- package/contracts/morpho/MorphoAdapterV1_1.sol +137 -0
- package/contracts/morpho/MorphoAdapterV1_2.sol +126 -0
- package/contracts/morpho/helpers/AggregatorV3Interface.sol +24 -0
- package/contracts/morpho/helpers/ChainlinkDataFeedLib.sol +36 -0
- package/contracts/morpho/helpers/ConstantsLib.sol +20 -0
- package/contracts/morpho/helpers/ErrorsLib.sol +17 -0
- package/contracts/morpho/helpers/IERC4626.sol +6 -0
- package/contracts/morpho/helpers/IMetaMorphoV1_1.sol +229 -0
- package/contracts/morpho/helpers/IMetaMorphoV1_1Factory.sol +32 -0
- package/contracts/morpho/helpers/IMorpho.sol +361 -0
- package/contracts/morpho/helpers/IMorphoCallbacks.sol +52 -0
- package/contracts/morpho/helpers/IMorphoChainlinkOracleV2.sol +39 -0
- package/contracts/morpho/helpers/IMorphoChainlinkOracleV2Factory.sol +56 -0
- package/contracts/morpho/helpers/IOracle.sol +15 -0
- package/contracts/morpho/helpers/MarketParamsLib.sol +21 -0
- package/contracts/morpho/helpers/MathLib.sol +45 -0
- package/contracts/morpho/helpers/Morpho.sol.bak +517 -0
- package/contracts/morpho/helpers/MorphoChainlinkOracleV2.sol +157 -0
- package/contracts/morpho/helpers/PendingLib.sol +47 -0
- package/contracts/morpho/helpers/SharesMathLib.sol +45 -0
- package/contracts/morpho/helpers/VaultLib.sol +18 -0
- package/contracts/reward/RewardDistributionV1.sol +110 -0
- package/contracts/reward/RewardRouterV0.sol +63 -0
- package/contracts/reward/Rewards.example.json +72 -0
- package/contracts/stablecoin/IStablecoin.sol +211 -0
- package/contracts/stablecoin/IStablecoinMetadata.sol +27 -0
- package/contracts/stablecoin/IStablecoinModifier.sol +52 -0
- package/contracts/stablecoin/Stablecoin.sol +376 -0
- package/contracts/stablecoin/libraries/ConstantsLib.sol +13 -0
- package/contracts/stablecoin/libraries/ErrorsLib.sol +45 -0
- package/contracts/stablecoin/libraries/EventsLib.sol +74 -0
- package/contracts/stablecoin/libraries/PendingLib.sol +38 -0
- package/contracts/vault/VaultAdapterRecoverV1.sol +29 -0
- package/contracts/vault/VaultAdapterV1.sol +126 -0
- package/dist/index.d.mts +16154 -0
- package/dist/index.d.ts +16154 -0
- package/dist/index.js +21134 -0
- package/dist/index.mjs +21061 -0
- package/docs/CoreVault: Integration of new Markets.md +197 -0
- package/docs/CoreVault: SupplyQueue.md +11 -0
- package/docs/Markets USDC Vault.md +35 -0
- package/docs/Markets USDU Vault.md +89 -0
- package/docs/Markets WETH Vault.md +35 -0
- package/docs/Overview.drawio +117 -0
- package/exports/abis/curve/CurveAdapterV1.ts +599 -0
- package/exports/abis/curve/CurveAdapterV1_1.ts +609 -0
- package/exports/abis/curve/CurveAdapterV1_2.ts +721 -0
- package/exports/abis/curve/helper/ICurveStableSwapNG.ts +1589 -0
- package/exports/abis/morpho/MorphoAdapterV1.ts +516 -0
- package/exports/abis/morpho/MorphoAdapterV1_1.ts +489 -0
- package/exports/abis/morpho/MorphoAdapterV1_2.ts +459 -0
- package/exports/abis/morpho/helper/AggregatorV3Interface.ts +113 -0
- package/exports/abis/morpho/helper/IMetaMorphoV1_1.ts +1483 -0
- package/exports/abis/morpho/helper/IMetaMorphoV1_1Base.ts +607 -0
- package/exports/abis/morpho/helper/IMetaMorphoV1_1StaticTyping.ts +696 -0
- package/exports/abis/morpho/helper/IMorpho.ts +1024 -0
- package/exports/abis/morpho/helper/IMorphoBase.ts +886 -0
- package/exports/abis/morpho/helper/IMorphoChainlinkOracleV2.ts +132 -0
- package/exports/abis/morpho/helper/IMorphoChainlinkOracleV2Factory.ts +109 -0
- package/exports/abis/morpho/helper/IMorphoFlashLoanCallback.ts +20 -0
- package/exports/abis/morpho/helper/IMorphoLiquidateCallback.ts +20 -0
- package/exports/abis/morpho/helper/IMorphoRepayCallback.ts +20 -0
- package/exports/abis/morpho/helper/IMorphoStaticTyping.ts +1003 -0
- package/exports/abis/morpho/helper/IMorphoSupplyCallback.ts +20 -0
- package/exports/abis/morpho/helper/IMorphoSupplyCollateralCallback.ts +20 -0
- package/exports/abis/morpho/helper/IMulticall.ts +21 -0
- package/exports/abis/morpho/helper/IOracle.ts +15 -0
- package/exports/abis/morpho/helper/IOwnable.ts +55 -0
- package/exports/abis/morpho/helper/MorphoChainlinkOracleV2.ts +188 -0
- package/exports/abis/openzeppelin/ERC20.ts +310 -0
- package/exports/abis/openzeppelin/ERC20Permit.ts +520 -0
- package/exports/abis/openzeppelin/IERC20.ts +185 -0
- package/exports/abis/openzeppelin/IERC20Metadata.ts +224 -0
- package/exports/abis/openzeppelin/IERC20Permit.ts +77 -0
- package/exports/abis/openzeppelin/IERC4626.ts +614 -0
- package/exports/abis/reward/RewardDistributionV1.ts +246 -0
- package/exports/abis/stablecoin/ErrorsLib.ts +114 -0
- package/exports/abis/stablecoin/EventsLib.ts +372 -0
- package/exports/abis/stablecoin/IStablecoin.ts +642 -0
- package/exports/abis/stablecoin/IStablecoinMetadata.ts +856 -0
- package/exports/abis/stablecoin/IStablecoinModifier.ts +15 -0
- package/exports/abis/stablecoin/Stablecoin.ts +1922 -0
- package/exports/abis/termmax/ITermMaxVault.ts +2335 -0
- package/exports/abis/vault/VaultAdapterRecoverV1.ts +490 -0
- package/exports/abis/vault/VaultAdapterV1.ts +459 -0
- package/exports/address.config.ts +113 -0
- package/exports/address.types.ts +130 -0
- package/exports/index.ts +61 -0
- package/hardhat.config.ts +231 -0
- package/helper/store.args.ts +17 -0
- package/helper/wallet.info.ts +3 -0
- package/helper/wallet.ts +41 -0
- package/install-macos.sh +46 -0
- package/package.json +73 -0
- package/tsconfig.json +15 -0
- package/tsup.config.ts +10 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
2
|
+
pragma solidity ^0.8.20;
|
|
3
|
+
|
|
4
|
+
import {Math} from '@openzeppelin/contracts/utils/math/Math.sol';
|
|
5
|
+
|
|
6
|
+
import {Context} from '@openzeppelin/contracts/utils/Context.sol';
|
|
7
|
+
import {IERC20Metadata} from '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';
|
|
8
|
+
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';
|
|
9
|
+
|
|
10
|
+
import {RewardDistributionV1, Stablecoin} from '../reward/RewardDistributionV1.sol';
|
|
11
|
+
|
|
12
|
+
import {ICurveStableSwapNG} from './helpers/ICurveStableSwapNG.sol';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @title CurveAdapterV1_1
|
|
16
|
+
* @author @samclassix <samclassix@proton.me>, @wrytlabs <wrytlabs@proton.me>
|
|
17
|
+
* @notice This is an adapter for interacting with ICurveStableSwapNG to mint liquidity straight into the pool under certain conditions.
|
|
18
|
+
*/
|
|
19
|
+
contract CurveAdapterV1_1 is RewardDistributionV1 {
|
|
20
|
+
using Math for uint256;
|
|
21
|
+
using SafeERC20 for IERC20Metadata;
|
|
22
|
+
using SafeERC20 for Stablecoin;
|
|
23
|
+
|
|
24
|
+
ICurveStableSwapNG public immutable pool;
|
|
25
|
+
IERC20Metadata public immutable coin;
|
|
26
|
+
|
|
27
|
+
uint256 public immutable idxS;
|
|
28
|
+
uint256 public immutable idxC;
|
|
29
|
+
|
|
30
|
+
uint256 public totalMinted;
|
|
31
|
+
uint256 public totalRevenue;
|
|
32
|
+
|
|
33
|
+
// ---------------------------------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
event AddLiquidity(address indexed sender, uint256 minted, uint256 totalMinted, uint256 sharesMinted, uint256 totalShares);
|
|
36
|
+
event RemoveLiquidity(address indexed sender, uint256 burned, uint256 totalMinted, uint256 sharesBurned, uint256 totalShares);
|
|
37
|
+
event Revenue(uint256 amount, uint256 totalRevenue, uint256 totalMinted);
|
|
38
|
+
|
|
39
|
+
// ---------------------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
error ImbalancedVariant(uint256[] balances);
|
|
42
|
+
error NotProfitable();
|
|
43
|
+
|
|
44
|
+
// ---------------------------------------------------------------------------------------
|
|
45
|
+
|
|
46
|
+
constructor(
|
|
47
|
+
ICurveStableSwapNG _pool,
|
|
48
|
+
uint256 _idxS, // IStablecoin
|
|
49
|
+
uint256 _idxC, // IERC20 coin
|
|
50
|
+
address[5] memory _receivers,
|
|
51
|
+
uint32[5] memory _weights
|
|
52
|
+
) RewardDistributionV1(Stablecoin(_pool.coins(_idxS)), _receivers, _weights) {
|
|
53
|
+
pool = _pool;
|
|
54
|
+
|
|
55
|
+
require(_idxS < 2, 'idxS out of bounds for max 2 tokens');
|
|
56
|
+
require(_idxC < 2, 'idxC out of bounds for max 2 tokens');
|
|
57
|
+
|
|
58
|
+
idxS = _idxS;
|
|
59
|
+
idxC = _idxC;
|
|
60
|
+
|
|
61
|
+
coin = IERC20Metadata(_pool.coins(_idxC));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ---------------------------------------------------------------------------------------
|
|
65
|
+
|
|
66
|
+
function checkImbalance() public view returns (bool) {
|
|
67
|
+
uint256 correctedAmount = (pool.balances(idxC) * 1 ether) / 10 ** coin.decimals();
|
|
68
|
+
if (pool.balances(idxS) <= correctedAmount) {
|
|
69
|
+
return true;
|
|
70
|
+
} else {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function verifyImbalance(bool state) public view {
|
|
76
|
+
if (checkImbalance() != state) revert ImbalancedVariant(pool.get_balances());
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// ---------------------------------------------------------------------------------------
|
|
80
|
+
|
|
81
|
+
function addLiquidity(uint256 amount, uint256 minShares) external returns (uint256) {
|
|
82
|
+
uint256 amountStable = (amount * 1 ether) / 10 ** coin.decimals();
|
|
83
|
+
|
|
84
|
+
// transfer coin token, needs approval
|
|
85
|
+
coin.safeTransferFrom(_msgSender(), address(this), amount);
|
|
86
|
+
|
|
87
|
+
// mint the same amountStable in stables
|
|
88
|
+
stable.mintModule(address(this), amountStable);
|
|
89
|
+
totalMinted += amountStable;
|
|
90
|
+
|
|
91
|
+
// approve tokens
|
|
92
|
+
stable.forceApprove(address(pool), amountStable);
|
|
93
|
+
coin.forceApprove(address(pool), amount);
|
|
94
|
+
|
|
95
|
+
// prepare amounts
|
|
96
|
+
uint256[] memory amounts = new uint256[](2);
|
|
97
|
+
amounts[idxS] = amountStable;
|
|
98
|
+
amounts[idxC] = amount;
|
|
99
|
+
|
|
100
|
+
// provide liquidity
|
|
101
|
+
uint256 shares = pool.add_liquidity(amounts, minShares * 2);
|
|
102
|
+
|
|
103
|
+
// verify imbalance for stable
|
|
104
|
+
verifyImbalance(true);
|
|
105
|
+
|
|
106
|
+
// return sender's split of shares
|
|
107
|
+
uint256 split = shares / 2;
|
|
108
|
+
pool.transfer(_msgSender(), split);
|
|
109
|
+
|
|
110
|
+
// emit event and return share split
|
|
111
|
+
emit AddLiquidity(_msgSender(), amountStable, totalMinted, split, pool.balanceOf(address(this)));
|
|
112
|
+
return split;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// ---------------------------------------------------------------------------------------
|
|
116
|
+
|
|
117
|
+
function calcProfitability(uint256 beforeLP, uint256 afterLP, uint256 split) public view returns (uint256) {
|
|
118
|
+
// @dev: if all debt is already paid, `calcBeforeSplit` will be 0 and therefore profit is the whole `split`
|
|
119
|
+
uint256 calcBeforeSplit = ((1 ether - ((afterLP * 1 ether) / beforeLP)) * totalMinted) / 1 ether;
|
|
120
|
+
if (split > calcBeforeSplit) {
|
|
121
|
+
return split - calcBeforeSplit;
|
|
122
|
+
} else {
|
|
123
|
+
return 0;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// ---------------------------------------------------------------------------------------
|
|
128
|
+
|
|
129
|
+
function removeLiquidity(uint256 shares, uint256 minAmount) external returns (uint256) {
|
|
130
|
+
// store LP balance
|
|
131
|
+
uint256 beforeLP = pool.balanceOf(address(this));
|
|
132
|
+
|
|
133
|
+
// transfer LP shares from sender, needs approval
|
|
134
|
+
pool.transferFrom(_msgSender(), address(this), shares);
|
|
135
|
+
|
|
136
|
+
// remove both shares and get split
|
|
137
|
+
uint256 split = pool.remove_liquidity_one_coin(shares * 2, int128(int256(idxS)), minAmount * 2) / 2;
|
|
138
|
+
|
|
139
|
+
// verify imbalance for coin
|
|
140
|
+
verifyImbalance(false);
|
|
141
|
+
|
|
142
|
+
// verify if in profit
|
|
143
|
+
uint256 afterLP = pool.balanceOf(address(this));
|
|
144
|
+
uint256 profit = calcProfitability(beforeLP, afterLP, split);
|
|
145
|
+
if (profit == 0) revert NotProfitable();
|
|
146
|
+
totalRevenue += profit;
|
|
147
|
+
|
|
148
|
+
// transfer split to sender
|
|
149
|
+
stable.transfer(_msgSender(), split);
|
|
150
|
+
|
|
151
|
+
// reconcile
|
|
152
|
+
uint256 burned = _reconcile();
|
|
153
|
+
|
|
154
|
+
// emit revenue with reduced totalMinted
|
|
155
|
+
emit Revenue(profit, totalRevenue, totalMinted);
|
|
156
|
+
|
|
157
|
+
// emit event and return share portion
|
|
158
|
+
emit RemoveLiquidity(_msgSender(), burned, totalMinted, shares, afterLP);
|
|
159
|
+
return split;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// ---------------------------------------------------------------------------------------
|
|
163
|
+
// redeem, onlyCurator
|
|
164
|
+
|
|
165
|
+
function redeem(uint256 shares, uint256 minAmount) external onlyCurator {
|
|
166
|
+
pool.remove_liquidity_one_coin(shares, int128(int256(idxS)), minAmount);
|
|
167
|
+
_reconcile();
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// ---------------------------------------------------------------------------------------
|
|
171
|
+
|
|
172
|
+
function payOffDebt() external onlyCuratorOrGuardian {
|
|
173
|
+
_reconcile();
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// ---------------------------------------------------------------------------------------
|
|
177
|
+
|
|
178
|
+
function _reconcile() internal returns (uint256) {
|
|
179
|
+
uint256 amount = stable.balanceOf(address(this));
|
|
180
|
+
if (totalMinted <= amount) {
|
|
181
|
+
if (totalMinted != 0) {
|
|
182
|
+
stable.burn(totalMinted);
|
|
183
|
+
totalMinted = 0;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// distribute remainings
|
|
187
|
+
_distribute();
|
|
188
|
+
|
|
189
|
+
return totalMinted;
|
|
190
|
+
} else {
|
|
191
|
+
// fallback, burn existing totalMinted if available,
|
|
192
|
+
// will leave with dust debt
|
|
193
|
+
stable.burn(amount);
|
|
194
|
+
totalMinted -= amount;
|
|
195
|
+
return amount;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|