Skip to content

Commit 14f37ed

Browse files
authored
Merge pull request #30 from morpho-org/style/owner-naming
owner => admin
2 parents 21a4ae4 + 01820d2 commit 14f37ed

File tree

5 files changed

+124
-38
lines changed

5 files changed

+124
-38
lines changed

src/PublicAllocator.sol

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ contract PublicAllocator is IPublicAllocatorStaticTyping {
3737
/* STORAGE */
3838

3939
/// @inheritdoc IPublicAllocatorBase
40-
mapping(address => address) public owner;
40+
mapping(address => address) public admin;
4141
/// @inheritdoc IPublicAllocatorBase
4242
mapping(address => uint256) public fee;
4343
/// @inheritdoc IPublicAllocatorBase
@@ -47,9 +47,11 @@ contract PublicAllocator is IPublicAllocatorStaticTyping {
4747

4848
/* MODIFIER */
4949

50-
/// @dev Reverts if the caller is not the owner for this vault or the vault owner.
51-
modifier onlyOwner(address vault) {
52-
if (msg.sender != owner[vault] && msg.sender != IMetaMorpho(vault).owner()) revert ErrorsLib.NotOwner();
50+
/// @dev Reverts if the caller is not the admin nor the owner of this vault.
51+
modifier onlyAdminOrVaultOwner(address vault) {
52+
if (msg.sender != admin[vault] && msg.sender != IMetaMorpho(vault).owner()) {
53+
revert ErrorsLib.NotAdminNorVaultOwner();
54+
}
5355
_;
5456
}
5557

@@ -60,24 +62,24 @@ contract PublicAllocator is IPublicAllocatorStaticTyping {
6062
MORPHO = IMorpho(morpho);
6163
}
6264

63-
/* OWNER ONLY */
65+
/* ADMIN OR VAULT OWNER ONLY */
6466

6567
/// @inheritdoc IPublicAllocatorBase
66-
function setOwner(address vault, address newOwner) external onlyOwner(vault) {
67-
if (owner[vault] == newOwner) revert ErrorsLib.AlreadySet();
68-
owner[vault] = newOwner;
69-
emit EventsLib.SetOwner(msg.sender, vault, newOwner);
68+
function setAdmin(address vault, address newAdmin) external onlyAdminOrVaultOwner(vault) {
69+
if (admin[vault] == newAdmin) revert ErrorsLib.AlreadySet();
70+
admin[vault] = newAdmin;
71+
emit EventsLib.SetAdmin(msg.sender, vault, newAdmin);
7072
}
7173

7274
/// @inheritdoc IPublicAllocatorBase
73-
function setFee(address vault, uint256 newFee) external onlyOwner(vault) {
75+
function setFee(address vault, uint256 newFee) external onlyAdminOrVaultOwner(vault) {
7476
if (fee[vault] == newFee) revert ErrorsLib.AlreadySet();
7577
fee[vault] = newFee;
7678
emit EventsLib.SetFee(msg.sender, vault, newFee);
7779
}
7880

7981
/// @inheritdoc IPublicAllocatorBase
80-
function setFlowCaps(address vault, FlowCapsConfig[] calldata config) external onlyOwner(vault) {
82+
function setFlowCaps(address vault, FlowCapsConfig[] calldata config) external onlyAdminOrVaultOwner(vault) {
8183
for (uint256 i = 0; i < config.length; i++) {
8284
if (config[i].caps.maxIn > MAX_SETTABLE_FLOW_CAP || config[i].caps.maxOut > MAX_SETTABLE_FLOW_CAP) {
8385
revert ErrorsLib.MaxSettableFlowCapExceeded();
@@ -89,7 +91,7 @@ contract PublicAllocator is IPublicAllocatorStaticTyping {
8991
}
9092

9193
/// @inheritdoc IPublicAllocatorBase
92-
function transferFee(address vault, address payable feeRecipient) external onlyOwner(vault) {
94+
function transferFee(address vault, address payable feeRecipient) external onlyAdminOrVaultOwner(vault) {
9395
uint256 claimed = accruedFee[vault];
9496
accruedFee[vault] = 0;
9597
feeRecipient.transfer(claimed);

src/interfaces/IPublicAllocator.sol

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,11 @@ struct Withdrawal {
3838
/// @dev This interface is used for factorizing IPublicAllocatorStaticTyping and IPublicAllocator.
3939
/// @dev Consider using the IPublicAllocator interface instead of this one.
4040
interface IPublicAllocatorBase {
41-
/// @notice The address of the Morpho contract.
41+
/// @notice The Morpho contract.
4242
function MORPHO() external view returns (IMorpho);
4343

44-
/// @notice The address of the owner of the public allocator config for a given vault.
45-
/// @dev The owner of the underlying vault always has the public allocator owner capabilities.
46-
function owner(address vault) external view returns (address);
44+
/// @notice The admin for a given vault.
45+
function admin(address vault) external view returns (address);
4746

4847
/// @notice The current ETH fee for a given vault.
4948
function fee(address vault) external view returns (uint256);
@@ -64,8 +63,8 @@ interface IPublicAllocatorBase {
6463
external
6564
payable;
6665

67-
/// @notice Sets the owner for a given vault.
68-
function setOwner(address vault, address newOwner) external;
66+
/// @notice Sets the admin for a given vault.
67+
function setAdmin(address vault, address newAdmin) external;
6968

7069
/// @notice Sets the fee for a given vault.
7170
function setFee(address vault, uint256 newFee) external;

src/libraries/ErrorsLib.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import {Id} from "../../lib/metamorpho/src/interfaces/IMetaMorpho.sol";
88
/// @custom:contact security@morpho.org
99
/// @notice Library exposing error messages.
1010
library ErrorsLib {
11-
/// @notice Thrown when the `msg.sender` is not the `owner`.
12-
error NotOwner();
11+
/// @notice Thrown when the `msg.sender` is not the admin nor the owner of the vault.
12+
error NotAdminNorVaultOwner();
1313

1414
/// @notice Thrown when the reallocation fee given is wrong.
1515
error IncorrectFee();

src/libraries/EventsLib.sol

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ library EventsLib {
1616
address indexed sender, address indexed vault, Id indexed supplyMarketId, uint256 suppliedAssets
1717
);
1818

19-
/// @notice Emitted when the owner is set for a vault.
20-
event SetOwner(address indexed sender, address indexed vault, address indexed owner);
19+
/// @notice Emitted when the admin is set for a vault.
20+
event SetAdmin(address indexed sender, address indexed vault, address admin);
2121

22-
/// @notice Emitted when the owner changes the `fee` for a vault.
22+
/// @notice Emitted when the fee is set for a vault.
2323
event SetFee(address indexed sender, address indexed vault, uint256 fee);
2424

25-
/// @notice Emitted when the owner transfers the fee for a vault.
25+
/// @notice Emitted when the fee is transfered for a vault.
2626
event TransferFee(address indexed sender, address indexed vault, uint256 amount, address indexed feeRecipient);
2727

28-
/// @notice Emitted when the owner updates some flow caps for a vault.
28+
/// @notice Emitted when the flow caps are set for a vault.
2929
event SetFlowCaps(address indexed sender, address indexed vault, FlowCapsConfig[] config);
3030
}

test/PublicAllocatorTest.sol

Lines changed: 98 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -73,20 +73,40 @@ contract PublicAllocatorTest is IntegrationTest {
7373
_sortSupplyQueueIdleLast();
7474
}
7575

76-
function testOwner() public {
77-
assertEq(publicAllocator.owner(address(vault)), address(0));
76+
function testAdmin() public {
77+
assertEq(publicAllocator.admin(address(vault)), address(0));
7878
}
7979

80-
function testSetOwner() public {
80+
function testSetAdmin() public {
8181
vm.prank(OWNER);
82-
publicAllocator.setOwner(address(vault), address(1));
83-
assertEq(publicAllocator.owner(address(vault)), address(1));
82+
publicAllocator.setAdmin(address(vault), address(1));
83+
assertEq(publicAllocator.admin(address(vault)), address(1));
8484
}
8585

86-
function testSetOwnerFail() public {
86+
function testSetAdminByAdmin(address sender, address newAdmin) public {
87+
vm.assume(publicAllocator.admin(address(vault)) != sender);
88+
vm.assume(sender != newAdmin);
89+
vm.prank(OWNER);
90+
publicAllocator.setAdmin(address(vault), sender);
91+
vm.prank(sender);
92+
publicAllocator.setAdmin(address(vault), newAdmin);
93+
assertEq(publicAllocator.admin(address(vault)), newAdmin);
94+
}
95+
96+
function testSetAdminAlreadySet() public {
8797
vm.expectRevert(ErrorsLib.AlreadySet.selector);
8898
vm.prank(OWNER);
89-
publicAllocator.setOwner(address(vault), address(0));
99+
publicAllocator.setAdmin(address(vault), address(0));
100+
}
101+
102+
function testSetAdminAccessFail(address sender, address newAdmin) public {
103+
vm.assume(sender != OWNER);
104+
vm.assume(publicAllocator.admin(address(vault)) != sender);
105+
vm.assume(publicAllocator.admin(address(vault)) != newAdmin);
106+
107+
vm.expectRevert(ErrorsLib.NotAdminNorVaultOwner.selector);
108+
vm.prank(sender);
109+
publicAllocator.setAdmin(address(vault), newAdmin);
90110
}
91111

92112
function testReallocateCapZeroOutflowByDefault(uint128 flow) public {
@@ -112,28 +132,28 @@ contract PublicAllocatorTest is IntegrationTest {
112132

113133
function testConfigureFlowAccessFail(address sender) public {
114134
vm.assume(sender != OWNER);
115-
vm.assume(sender != address(0));
135+
vm.assume(publicAllocator.admin(address(vault)) != sender);
116136

117137
flowCaps.push(FlowCapsConfig(idleParams.id(), FlowCaps(0, 0)));
118138

119139
vm.prank(sender);
120-
vm.expectRevert(ErrorsLib.NotOwner.selector);
140+
vm.expectRevert(ErrorsLib.NotAdminNorVaultOwner.selector);
121141
publicAllocator.setFlowCaps(address(vault), flowCaps);
122142
}
123143

124144
function testTransferFeeAccessFail(address sender, address payable recipient) public {
125145
vm.assume(sender != OWNER);
126-
vm.assume(sender != address(0));
146+
vm.assume(publicAllocator.admin(address(vault)) != sender);
127147
vm.prank(sender);
128-
vm.expectRevert(ErrorsLib.NotOwner.selector);
148+
vm.expectRevert(ErrorsLib.NotAdminNorVaultOwner.selector);
129149
publicAllocator.transferFee(address(vault), recipient);
130150
}
131151

132152
function testSetFeeAccessFail(address sender, uint256 fee) public {
133153
vm.assume(sender != OWNER);
134-
vm.assume(sender != address(0));
154+
vm.assume(publicAllocator.admin(address(vault)) != sender);
135155
vm.prank(sender);
136-
vm.expectRevert(ErrorsLib.NotOwner.selector);
156+
vm.expectRevert(ErrorsLib.NotAdminNorVaultOwner.selector);
137157
publicAllocator.setFee(address(vault), fee);
138158
}
139159

@@ -146,6 +166,18 @@ contract PublicAllocatorTest is IntegrationTest {
146166
assertEq(publicAllocator.fee(address(vault)), fee);
147167
}
148168

169+
function testSetFeeByAdmin(uint256 fee, address sender) public {
170+
vm.assume(publicAllocator.admin(address(vault)) != sender);
171+
vm.assume(fee != publicAllocator.fee(address(vault)));
172+
vm.prank(OWNER);
173+
publicAllocator.setAdmin(address(vault), sender);
174+
vm.prank(sender);
175+
vm.expectEmit(address(publicAllocator));
176+
emit EventsLib.SetFee(sender, address(vault), fee);
177+
publicAllocator.setFee(address(vault), fee);
178+
assertEq(publicAllocator.fee(address(vault)), fee);
179+
}
180+
149181
function testSetFeeAlreadySet(uint256 fee) public {
150182
vm.assume(fee != publicAllocator.fee(address(vault)));
151183
vm.prank(OWNER);
@@ -180,6 +212,35 @@ contract PublicAllocatorTest is IntegrationTest {
180212
assertEq(flowCap.maxOut, out1);
181213
}
182214

215+
function testSetFlowCapsByAdmin(uint128 in0, uint128 out0, uint128 in1, uint128 out1, address sender) public {
216+
vm.assume(publicAllocator.admin(address(vault)) != sender);
217+
in0 = uint128(bound(in0, 0, MAX_SETTABLE_FLOW_CAP));
218+
out0 = uint128(bound(out0, 0, MAX_SETTABLE_FLOW_CAP));
219+
in1 = uint128(bound(in1, 0, MAX_SETTABLE_FLOW_CAP));
220+
out1 = uint128(bound(out1, 0, MAX_SETTABLE_FLOW_CAP));
221+
222+
flowCaps.push(FlowCapsConfig(idleParams.id(), FlowCaps(in0, out0)));
223+
flowCaps.push(FlowCapsConfig(allMarkets[0].id(), FlowCaps(in1, out1)));
224+
225+
vm.prank(OWNER);
226+
publicAllocator.setAdmin(address(vault), sender);
227+
228+
vm.expectEmit(address(publicAllocator));
229+
emit EventsLib.SetFlowCaps(sender, address(vault), flowCaps);
230+
231+
vm.prank(sender);
232+
publicAllocator.setFlowCaps(address(vault), flowCaps);
233+
234+
FlowCaps memory flowCap;
235+
flowCap = publicAllocator.flowCaps(address(vault), idleParams.id());
236+
assertEq(flowCap.maxIn, in0);
237+
assertEq(flowCap.maxOut, out0);
238+
239+
flowCap = publicAllocator.flowCaps(address(vault), allMarkets[0].id());
240+
assertEq(flowCap.maxIn, in1);
241+
assertEq(flowCap.maxOut, out1);
242+
}
243+
183244
function testPublicReallocateEvent(uint128 flow, address sender) public {
184245
flow = uint128(bound(flow, 1, CAP2 / 2));
185246

@@ -298,6 +359,30 @@ contract PublicAllocatorTest is IntegrationTest {
298359
assertEq(address(this).balance - before, 2 * 0.001 ether, "wrong fee transferred");
299360
}
300361

362+
function testTransferFeeByAdminSuccess(address sender) public {
363+
vm.assume(publicAllocator.admin(address(vault)) != sender);
364+
vm.prank(OWNER);
365+
publicAllocator.setAdmin(address(vault), sender);
366+
vm.prank(sender);
367+
publicAllocator.setFee(address(vault), 0.001 ether);
368+
369+
flowCaps.push(FlowCapsConfig(idleParams.id(), FlowCaps(0, 2 ether)));
370+
flowCaps.push(FlowCapsConfig(allMarkets[0].id(), FlowCaps(2 ether, 0)));
371+
vm.prank(OWNER);
372+
publicAllocator.setFlowCaps(address(vault), flowCaps);
373+
withdrawals.push(Withdrawal(idleParams, 1 ether));
374+
375+
publicAllocator.reallocateTo{value: 0.001 ether}(address(vault), withdrawals, allMarkets[0]);
376+
publicAllocator.reallocateTo{value: 0.001 ether}(address(vault), withdrawals, allMarkets[0]);
377+
378+
uint256 before = address(this).balance;
379+
380+
vm.prank(sender);
381+
publicAllocator.transferFee(address(vault), payable(address(this)));
382+
383+
assertEq(address(this).balance - before, 2 * 0.001 ether, "wrong fee transferred");
384+
}
385+
301386
function testTransferFeeFail() public {
302387
vm.prank(OWNER);
303388
publicAllocator.setFee(address(vault), 0.001 ether);

0 commit comments

Comments
 (0)