FeeConfigurator Contract

Last Update: February 2023
The BeefyFeeConfigurator Contract is an infrastructure contract hosted on each of the blockchains which Beefy has deployed on. The contract manages the configuration of fees for each strategy on the relevant chain, which the StratFeeManager Contract interfaces with through IFeeConfig.sol.
The relevant address for the FeeConfigurator Contract ("beefyFeeConfig") on each chain is displayed in the Beefy API using the GET /config endpoint.


Includes a standard onlyManager() modifier to control access to write functions.
modifier onlyManager() {
require(msg.sender == owner() || msg.sender == keeper, "!manager");

View Functions


Returns a FeeCategory structure for a specific strategy address argument, displaying the total fees charged, the fees for Beefy, the harvest caller and the strategist, a string showing the description of the type of fee category, and "active" boolean variable, showing whether the fee category is switched on or not.
Includes an "_adjust" boolean variable argument, which displays fees as a % of the total harvest if set to true, or as a % of the total fee if set to false.
function getFees(address _strategy) external view returns (FeeCategory memory) {
return getFeeCategory(stratFeeId[_strategy], false);
function getFees(address _strategy, bool _adjust) external view returns (FeeCategory memory) {
return getFeeCategory(stratFeeId[_strategy], _adjust);


Returns a FeeCategory structure for a specific strategy ID integer, as described above. Also includes the "_adjust" boolean variable option.
function getFeeCategory(uint256 _id, bool _adjust) public view returns (FeeCategory memory fees) {
uint256 id = feeCategory[_id].active ? _id : 0;
fees = feeCategory[id];
if (_adjust) {
uint256 _totalFee =;
fees.beefy = fees.beefy * _totalFee / DIVISOR; = * _totalFee / DIVISOR;
fees.strategist = fees.strategist * _totalFee / DIVISOR;

Write Functions


Updates the stratFeeId mapping to show ultimately what FeeCategory structure is being used by a particular strategy, by way of an intermediate feeCategory mapping and feeId integer values.
This includes 3 options, including one for the strategy to update its own feeId, one to stipulate the strategy address and feeId as arguments, and one to set a range of strategies by giving both an array of strategy addresses and an array of feeIds as arguments. Each of the three then use the internal _setStratFeeId() function to update each strategy.
function setStratFeeId(uint256 _feeId) external {
_setStratFeeId(msg.sender, _feeId);
function setStratFeeId(address _strategy, uint256 _feeId) external onlyManager {
_setStratFeeId(_strategy, _feeId);
function setStratFeeId(address[] memory _strategies, uint256[] memory _feeIds) external onlyManager {
uint256 stratLength = _strategies.length;
for (uint256 i = 0; i < stratLength; i++) {
_setStratFeeId(_strategies[i], _feeIds[i]);
function _setStratFeeId(address _strategy, uint256 _feeId) internal {
stratFeeId[_strategy] = _feeId;
emit SetStratFeeId(_strategy, _feeId);


Sets the parameters for a given FeeCategory structure (new or existing), including the split in fees between Beefy, the harvest caller and the strategist.
function setFeeCategory(
uint256 _id,
uint256 _total,
uint256 _call,
uint256 _strategist,
string memory _label,
bool _active,
bool _adjust
) external onlyOwner {
require(_total <= totalLimit, ">totalLimit");
if (_adjust) {
_call = _call * DIVISOR / _total;
_strategist = _strategist * DIVISOR / _total;
uint256 beefy = DIVISOR - _call - _strategist;
FeeCategory memory category = FeeCategory(_total, beefy, _call, _strategist, _label, _active);
feeCategory[_id] = category;
emit SetFeeCategory(_id, _total, beefy, _call, _strategist, _label, _active);


Updates the named keeper in the FeeConfigurator contract.
function setKeeper(address _keeper) external onlyManager {
keeper = _keeper;
emit SetKeeper(_keeper);

pause() / unpause()

Sets a specific FeeCategory (using the category ID as an argument) to either active ("unpaused") - meaning a strategy set to that category will use that category - or inactive ("paused") - meaning the strategy will revert to the default fee configuration.
function pause(uint256 _id) external onlyManager {
feeCategory[_id].active = false;
emit Pause(_id);
function unpause(uint256 _id) external onlyManager {
feeCategory[_id].active = true;
emit Unpause(_id);