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

build: seperate the structs #80

Closed
wants to merge 1 commit into from
Closed
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
61 changes: 38 additions & 23 deletions src/TokenizedStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -244,18 +244,18 @@ contract TokenizedStrategy {
uint32 profitMaxUnlockTime; // The amount of seconds that the reported profit unlocks over.
uint16 performanceFee; // The percent in basis points of profit that is charged as a fee.
address performanceFeeRecipient; // The address to pay the `performanceFee` to.
bool shutdown; // Bool that can be used to stop deposits into the strategy.
}


struct Management {
// Strategy status checks.
bool entered; // Bool to prevent reentrancy.
// Access management variables.
address management; // Main address that can set all configurable variables.
address keeper; // Address given permission to call {report} and {tend}.
address pendingManagement; // Address that is pending to take over `management`.
address emergencyAdmin; // Address to act in emergencies as well as `management`.
mapping(bytes4 => mapping(address => bool)) allowed; // Mapping from a function selector to if an address can call it.

// Strategy status checks.
bool entered; // Bool to prevent reentrancy.
bool shutdown; // Bool that can be used to stop deposits into the strategy.
}

/*//////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -302,7 +302,7 @@ contract TokenizedStrategy {
* Placed over all state changing functions for increased safety.
*/
modifier nonReentrant() {
StrategyData storage S = _strategyStorage();
Management storage S = _managementStorage();
// On the first call to nonReentrant, `entered` will be false
require(!S.entered, "ReentrancyGuard: reentrant call");

Expand All @@ -327,7 +327,7 @@ contract TokenizedStrategy {
* @param _sender The original msg.sender.
*/
function isManagement(address _sender) public view returns (bool) {
return _sender == _strategyStorage().management;
return _sender == _managementStorage().management;
}

/**
Expand All @@ -343,7 +343,7 @@ contract TokenizedStrategy {
* @param _sender The original msg.sender.
*/
function isKeeperOrManagement(address _sender) public view returns (bool) {
StrategyData storage S = _strategyStorage();
Management storage S = _managementStorage();
return _sender == S.keeper || _sender == S.management;
}

Expand All @@ -360,7 +360,7 @@ contract TokenizedStrategy {
* @param _sender The original msg.sender.
*/
function isEmergencyAuthorized(address _sender) public view returns (bool) {
StrategyData storage S = _strategyStorage();
Management storage S = _managementStorage();
return _sender == S.emergencyAdmin || _sender == S.management;
}

Expand Down Expand Up @@ -409,6 +409,9 @@ contract TokenizedStrategy {
bytes32 internal constant BASE_STRATEGY_STORAGE =
bytes32(uint256(keccak256("yearn.base.strategy.storage")) - 1);

bytes32 internal constant MANAGEMENT_STRATEGY_STORAGE =
bytes32(uint256(keccak256("yearn.management.strategy.storage")) - 1);

/*//////////////////////////////////////////////////////////////
STORAGE GETTER FUNCTION
//////////////////////////////////////////////////////////////*/
Expand All @@ -430,6 +433,15 @@ contract TokenizedStrategy {
}
}

function _managementStorage() internal pure returns (Management storage S) {
// Since STORAGE_SLOT is a constant, we have to put a variable
// on the stack to access it from an inline assembly block.
bytes32 slot = MANAGEMENT_STRATEGY_STORAGE;
assembly {
S.slot := slot
}
}

/*//////////////////////////////////////////////////////////////
INITIALIZATION OF DEFAULT STORAGE
//////////////////////////////////////////////////////////////*/
Expand Down Expand Up @@ -494,9 +506,9 @@ contract TokenizedStrategy {

// Set the default management address. Can't be 0.
require(_management != address(0), "ZERO ADDRESS");
S.management = _management;
_managementStorage().management = _management;
// Set the keeper address
S.keeper = _keeper;
_managementStorage().keeper = _keeper;

// Emit event to signal a new strategy has been initialized.
emit NewTokenizedStrategy(address(this), _asset, API_VERSION);
Expand Down Expand Up @@ -1412,31 +1424,31 @@ contract TokenizedStrategy {
* @return . Address of management
*/
function management() external view returns (address) {
return _strategyStorage().management;
return _managementStorage().management;
}

/**
* @notice Get the current pending management address if any.
* @return . Address of pendingManagement
*/
function pendingManagement() external view returns (address) {
return _strategyStorage().pendingManagement;
return _managementStorage().pendingManagement;
}

/**
* @notice Get the current address that can call tend and report.
* @return . Address of the keeper
*/
function keeper() external view returns (address) {
return _strategyStorage().keeper;
return _managementStorage().keeper;
}

/**
* @notice Get the current address that can shutdown and emergency withdraw.
* @return . Address of the emergencyAdmin
*/
function emergencyAdmin() external view returns (address) {
return _strategyStorage().emergencyAdmin;
return _managementStorage().emergencyAdmin;
}

/**
Expand Down Expand Up @@ -1518,7 +1530,7 @@ contract TokenizedStrategy {
bytes4 _selector,
address _sender
) public view returns (bool) {
return _strategyStorage().allowed[_selector][_sender];
return _managementStorage().allowed[_selector][_sender];
}

/**
Expand All @@ -1545,7 +1557,7 @@ contract TokenizedStrategy {
*/
function setPendingManagement(address _management) external onlyManagement {
require(_management != address(0), "ZERO ADDRESS");
_strategyStorage().pendingManagement = _management;
_managementStorage().pendingManagement = _management;

emit UpdatePendingManagement(_management);
}
Expand All @@ -1555,9 +1567,12 @@ contract TokenizedStrategy {
* @dev Can only be called by the current `pendingManagement`.
*/
function acceptManagement() external {
require(msg.sender == _strategyStorage().pendingManagement, "!pending");
_strategyStorage().management = msg.sender;
_strategyStorage().pendingManagement = address(0);
require(
msg.sender == _managementStorage().pendingManagement,
"!pending"
);
_managementStorage().management = msg.sender;
_managementStorage().pendingManagement = address(0);

emit UpdateManagement(msg.sender);
}
Expand All @@ -1569,7 +1584,7 @@ contract TokenizedStrategy {
* @param _keeper New address to set `keeper` to.
*/
function setKeeper(address _keeper) external onlyManagement {
_strategyStorage().keeper = _keeper;
_managementStorage().keeper = _keeper;

emit UpdateKeeper(_keeper);
}
Expand All @@ -1583,7 +1598,7 @@ contract TokenizedStrategy {
function setEmergencyAdmin(
address _emergencyAdmin
) external onlyManagement {
_strategyStorage().emergencyAdmin = _emergencyAdmin;
_managementStorage().emergencyAdmin = _emergencyAdmin;

emit UpdateEmergencyAdmin(_emergencyAdmin);
}
Expand Down Expand Up @@ -1664,7 +1679,7 @@ contract TokenizedStrategy {
address _sender,
bool _allowed
) external onlyManagement {
_strategyStorage().allowed[_selector][_sender] = _allowed;
_managementStorage().allowed[_selector][_sender] = _allowed;

emit UpdateAllowed(_selector, _sender, _allowed);
}
Expand Down
10 changes: 10 additions & 0 deletions src/test/mocks/MockStorage.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.18;

import {TokenizedStrategy} from "../../TokenizedStrategy.sol";

contract MockStorage {
TokenizedStrategy.StrategyData public slot0;
TokenizedStrategy.Management public slot1;
uint256 public slot3;
}
Loading