Fees

The TipJar is a core component of the Summer Protocol that manages and distributes protocol fees to reward participants. Every vault in the protocol charges a 1% fee on Assets Under Management (AUM), which flows into the TipJar.

When users deposit assets into a vault, they receive shares representing their portion of the vault. As fees accumulate, the TipJar mints new shares that slightly dilute existing shareholders. For example, in a vault with $1,000 in assets and 1,000 shares, minting one new share for the TipJar would make each share worth approximately $0.999 instead of $1.

These fees are distributed to protocol participants through the TipJar, which can be configured to send rewards to different addresses based on governance decisions. The TipJar ensures transparent and automated fee distribution while maintaining the protocol's economic incentives.

The TipJar can be paused by protocol governance in emergency situations, and its distribution parameters can be adjusted to adapt to changing protocol needs.

Total Supply and Tip Accrual

function totalSupply() public view override(ERC20, IERC20) returns (uint256) {
    if (_isCollectingTip()) {
        return super.totalSupply();
    }
    uint256 _totalSupply = super.totalSupply();
    return _totalSupply + previewTip(tipJar(), _totalSupply);
}

This function manages the total supply accounting while considering tips. When the contract is collecting tips (_isCollectingTip()), it returns the raw total supply. Otherwise, it adds the pending tip amount to the total supply to provide an accurate representation of all shares.

Tip Collection

function tip() public whenNotPaused returns (uint256) {
    return _accrueTip(tipJar(), totalSupply());
}

Initiates the tip collection process when the contract isn't paused. It calculates and mints new shares to the TipJar based on the current tip rate and total supply.

Shake Function - Distribution

function shake(address fleetCommander_) external whenNotPaused {
    if (!IHarborCommand(harborCommand()).activeFleetCommanders(fleetCommander_)) {
        revert InvalidFleetCommanderAddress();
    }

    IFleetCommander fleetCommander = IFleetCommander(fleetCommander_);
    uint256 shares = fleetCommander.balanceOf(address(this));
    
    if (shares == 0) {
        emit TipJarShaken(address(fleetCommander), 0);
        return;
    }

    uint256 withdrawnAssets = fleetCommander.redeem(
        Constants.MAX_UINT256,
        address(this),
        address(this)
    );

    // Distribution continues with transfer of assets to recipients

The shake function is the core distribution mechanism. It:

  1. Verifies the FleetCommander is active

  2. Checks for available shares

  3. Redeems all shares for underlying assets

  4. Distributes the assets according to configured allocations

Batch Distribution

function shakeAll() public {
    address[] memory activeFleetCommanders = IHarborCommand(harborCommand())
        .getActiveFleetCommanders();
    _shakeMultiple(activeFleetCommanders);
}

Provides a convenience function to distribute rewards from all active FleetCommanders in a single transaction.

Last updated

Was this helpful?