Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reallocate by withdrawals + sink #5

Merged
merged 42 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
3473c5d
feat: reallocate by withdrawals + sink
adhusson Feb 13, 2024
8048f5e
chore: remove dead code/comment
adhusson Feb 13, 2024
f11432d
fix: add back fee check
adhusson Feb 13, 2024
79cebbf
fix: add back reallocate call + cap check
adhusson Feb 13, 2024
ca196c5
test: adapt tests
adhusson Feb 13, 2024
09793b5
Merge branch 'feat/flows-and-eth-fee' into feat/reallocate-by-flow
adhusson Feb 13, 2024
4e137bf
Merge branch 'feat/flows-and-eth-fee' into feat/reallocate-by-flow
adhusson Feb 14, 2024
9025853
Merge branch 'feat/flows-and-eth-fee' into feat/reallocate-by-flow
adhusson Feb 15, 2024
22c075b
fmt: forge fmt
adhusson Feb 15, 2024
a510cf1
Merge branch 'feat/flows-and-eth-fee' into feat/reallocate-by-flow
adhusson Feb 15, 2024
a09243a
feat: add withdrawTo-specific events
adhusson Feb 15, 2024
1fd4621
fmt: fmt
adhusson Feb 15, 2024
94d3fcc
Merge branch 'feat/flows-and-eth-fee' into feat/reallocate-by-flow
adhusson Feb 15, 2024
8b616ae
Merge branch 'feat/flows-and-eth-fee' into feat/reallocate-by-flow
adhusson Feb 15, 2024
3f0ea62
fix: protect against duplicates with nonzero assets in withdrawTo arg…
adhusson Feb 15, 2024
58d8b1d
chore: remove console2 import
adhusson Feb 15, 2024
0b285d5
Merge branch 'feat/flows-and-eth-fee' into feat/reallocate-by-flow
adhusson Feb 16, 2024
8e391ad
doc: natspec
adhusson Feb 16, 2024
a12f860
fix: canonical loop increment form
adhusson Feb 16, 2024
172f02c
feat: PublicAllocatorFactory, restricted to vaults created by a MetaM…
adhusson Feb 16, 2024
9c28448
feat: safe max value for flow caps
adhusson Feb 16, 2024
40e2700
Merge branch 'feat/reallocate-by-flow' into fix/duplicates-in-realloc…
adhusson Feb 16, 2024
4003542
chore: fmt
MathisGD Feb 16, 2024
2d69ebc
docs: minor fix
MathisGD Feb 16, 2024
ea4d87f
fix: small compilation issues
QGarchery Feb 16, 2024
366493a
Merge pull request #10 from morpho-org/fix/small-issues-duplicates
QGarchery Feb 16, 2024
fc3c880
feat: max settable flow cap as an integer
QGarchery Feb 16, 2024
c5a55f7
Merge pull request #9 from morpho-org/feat/safe-max-flow-cap
adhusson Feb 16, 2024
ce71ee7
refactor: rename depositAssets -> depositMarketAssets
adhusson Feb 16, 2024
9b75c1c
refactor: alternative fix for duplicates
MathisGD Feb 16, 2024
96443b7
rename depositMarketAssets -> vaultSupplyInMarket
adhusson Feb 16, 2024
102b1eb
Merge branch 'feat/reallocate-by-flow' into fix/duplicates-in-realloc…
adhusson Feb 16, 2024
e63d942
Merge branch 'feat/flows-and-eth-fee' into feat/reallocate-by-flow
adhusson Feb 16, 2024
87d45ff
Merge branch 'feat/reallocate-by-flow' into fix/duplicates-in-realloc…
adhusson Feb 16, 2024
bc945f4
Merge branch 'fix/duplicates-in-reallocate-by-flow' into fix/duplicat…
adhusson Feb 16, 2024
eb9eeb4
feat: accrue interest before computing expect supply assets
adhusson Feb 16, 2024
2ff7a7f
Merge remote-tracking branch 'origin/feat/flows-and-eth-fee' into fea…
MathisGD Feb 16, 2024
fbdcf06
Merge remote-tracking branch 'origin/feat/reallocate-by-flow' into fe…
MathisGD Feb 16, 2024
86fd595
feat: remove clamp
MathisGD Feb 16, 2024
d9bbfc5
Merge branch 'feat/reallocate-by-flow' into fix/duplicates-2
MathisGD Feb 16, 2024
de0022a
chore: fmt
MathisGD Feb 16, 2024
cfadc41
Merge pull request #11 from morpho-org/fix/duplicates-2
MathisGD Feb 16, 2024
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
2 changes: 1 addition & 1 deletion lib/metamorpho
Submodule metamorpho updated 0 files
61 changes: 37 additions & 24 deletions src/PublicAllocator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ import {UtilsLib} from "./libraries/UtilsLib.sol";

import {ErrorsLib} from "./libraries/ErrorsLib.sol";
import {EventsLib} from "./libraries/EventsLib.sol";
import {FlowCap, FlowConfig, SupplyConfig, IPublicAllocatorStaticTyping} from "./interfaces/IPublicAllocator.sol";
import {
FlowCap,
FlowConfig,
SupplyConfig,
Withdrawal,
IPublicAllocatorStaticTyping
} from "./interfaces/IPublicAllocator.sol";

contract PublicAllocator is IPublicAllocatorStaticTyping {
using MorphoLib for IMorpho;
Expand Down Expand Up @@ -59,36 +65,43 @@ contract PublicAllocator is IPublicAllocatorStaticTyping {

/// PUBLIC ///

function reallocate(MarketAllocation[] calldata allocations) external payable {
function withdrawTo(Withdrawal[] calldata withdrawals, MarketParams calldata depositMarketParams)
external
payable
{
if (msg.value != fee) revert ErrorsLib.IncorrectFee(msg.value);

uint256[] memory assets = new uint256[](allocations.length);
for (uint256 i = 0; i < allocations.length; ++i) {
// Do not compute interest twice for every market
MORPHO.accrueInterest(allocations[i].marketParams);
assets[i] = MORPHO.expectedSupplyAssets(allocations[i].marketParams, address(VAULT));
}
MarketAllocation[] memory allocations = new MarketAllocation[](withdrawals.length + 1);
allocations[withdrawals.length].marketParams = depositMarketParams;
allocations[withdrawals.length].assets = type(uint256).max;

VAULT.reallocate(allocations);
uint128 totalWithdrawn;

MarketParams memory marketParams;
for (uint256 i = 0; i < allocations.length; ++i) {
marketParams = allocations[i].marketParams;
Id id = marketParams.id();
uint256 newAssets = MORPHO.expectedSupplyAssets(marketParams, address(VAULT));
if (newAssets >= assets[i]) {
if (newAssets > supplyCap[id]) revert ErrorsLib.PublicAllocatorSupplyCapExceeded(id);
uint128 inflow = (newAssets - assets[i]).toUint128();
flowCap[id].maxIn -= inflow;
flowCap[id].maxOut = (flowCap[id].maxOut).saturatingAdd(inflow);
} else {
uint128 outflow = (assets[i] - newAssets).toUint128();
flowCap[id].maxIn = (flowCap[id].maxIn).saturatingAdd(outflow);
flowCap[id].maxOut -= outflow;
for (uint256 i = 0; i < withdrawals.length; ++i) {
allocations[i].marketParams = withdrawals[i].marketParams;
Id id = withdrawals[i].marketParams.id();
uint256 assets = MORPHO.expectedSupplyAssets(withdrawals[i].marketParams, address(VAULT));
adhusson marked this conversation as resolved.
Show resolved Hide resolved
uint128 withdrawnAssets = withdrawals[i].amount;
// Clamp at 0 if withdrawnAssets is too big
if (withdrawnAssets > assets) {
withdrawnAssets = assets.toUint128();
}
MathisGD marked this conversation as resolved.
Show resolved Hide resolved

totalWithdrawn += withdrawnAssets;
allocations[i].assets = assets - withdrawnAssets;
MathisGD marked this conversation as resolved.
Show resolved Hide resolved
flowCap[id].maxIn = (flowCap[id].maxIn).saturatingAdd(withdrawnAssets);
flowCap[id].maxOut -= withdrawnAssets;
emit EventsLib.PublicWithdrawal(id, withdrawnAssets);
}

emit EventsLib.PublicReallocate(msg.sender, msg.value);
VAULT.reallocate(allocations);

Id depositMarketId = depositMarketParams.id();
uint256 depositAssets = MORPHO.expectedSupplyAssets(depositMarketParams, address(VAULT));
QGarchery marked this conversation as resolved.
Show resolved Hide resolved
adhusson marked this conversation as resolved.
Show resolved Hide resolved
if (depositAssets > supplyCap[depositMarketId]) revert ErrorsLib.PublicAllocatorSupplyCapExceeded(depositMarketId);
flowCap[depositMarketId].maxIn -= totalWithdrawn;
flowCap[depositMarketId].maxOut = (flowCap[depositMarketId].maxOut).saturatingAdd(totalWithdrawn);
emit EventsLib.PublicReallocateTo(msg.sender, fee, depositMarketId, totalWithdrawn);
}

/// OWNER ONLY ///
Expand Down
11 changes: 9 additions & 2 deletions src/interfaces/IPublicAllocator.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.21;

import {IMetaMorpho, IMorpho, MarketAllocation, Id} from "../../lib/metamorpho/src/interfaces/IMetaMorpho.sol";
import {IMetaMorpho, IMorpho, MarketAllocation, Id, MarketParams} from "../../lib/metamorpho/src/interfaces/IMetaMorpho.sol";

struct FlowCap {
uint128 maxIn;
Expand All @@ -18,6 +18,11 @@ struct SupplyConfig {
uint256 cap;
}

struct Withdrawal {
MarketParams marketParams;
uint128 amount;
}

/// @dev This interface is used for factorizing IPublicAllocatorStaticTyping and IPublicAllocator.
/// @dev Consider using the IPublicAllocator interface instead of this one.
interface IPublicAllocatorBase {
Expand All @@ -28,7 +33,9 @@ interface IPublicAllocatorBase {
function fee() external view returns (uint256);
function supplyCap(Id) external view returns (uint256);

function reallocate(MarketAllocation[] calldata allocations) external payable;
function withdrawTo(Withdrawal[] calldata withdrawals, MarketParams calldata depositMarketParams)
external
payable;
function setFee(uint256 _fee) external;
function transferFee(address payable feeRecipient) external;
function setFlowCaps(FlowConfig[] calldata _flowCaps) external;
Expand Down
11 changes: 7 additions & 4 deletions src/libraries/EventsLib.sol
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

import {FlowConfig, SupplyConfig} from "../interfaces/IPublicAllocator.sol";
import {FlowConfig, SupplyConfig, Id} from "../interfaces/IPublicAllocator.sol";

/// @title EventsLib
/// @author Morpho Labs
/// @custom:contact [email protected]
/// @notice Library exposing events.
library EventsLib {
/// @notice Emitted when the public reallocation is triggered.
event PublicReallocate(address sender, uint256 fee);
/// @notice Emitted when the owner changes the `fee`.
/// @notice Emitted during a public reallocation for each withdrawn-from market
event PublicWithdrawal(Id id, uint256 withdrawnAssets);
MathisGD marked this conversation as resolved.
Show resolved Hide resolved
/// @notice Emitted at the end of a public reallocation
event PublicReallocateTo(address sender, uint256 fee, Id depositMarketId, uint256 depositedAssets);

MathisGD marked this conversation as resolved.
Show resolved Hide resolved
/// @notice Emitted when the owner changes the `fee`
event SetFee(uint256 fee);
/// @notice Emitted when the owner transfers the fee.
event TransferFee(uint256 amount);
Expand Down
Loading