- This contract calculates and pays lending/borrow fees and rewards. (FeesHelper.sol)
View Source: contracts/mixins/FeesHelper.sol
↗ Extends: State, FeesEvents ↘ Derived Contracts: InterestUser, SwapsUser
- _getTradingFee(uint256 feeTokenAmount)
- _getSwapExternalFee(uint256 feeTokenAmount)
- _getBorrowingFee(uint256 feeTokenAmount)
- _payTradingFeeToAffiliate(address referrer, address trader, address feeToken, uint256 tradingFee)
- _payTradingFee(address user, bytes32 loanId, address feeToken, address feeTokenPair, uint256 tradingFee)
- _payBorrowingFee(address user, bytes32 loanId, address feeToken, address feeTokenPair, uint256 borrowingFee)
- _payLendingFee(address user, address feeToken, uint256 lendingFee)
- _settleFeeRewardForInterestExpense(struct LoanInterestStruct.LoanInterest loanInterestLocal, bytes32 loanId, address feeToken, address feeTokenPair, address user, uint256 interestTime)
- _payFeeReward(address user, bytes32 loanId, address feeToken, address feeTokenPair, uint256 feeAmount)
Calculate trading fee.
function _getTradingFee(uint256 feeTokenAmount) internal view
returns(uint256)
Arguments
Name | Type | Description |
---|---|---|
feeTokenAmount | uint256 | The amount of tokens to trade. |
Returns
The fee of the trade.
Source Code
function _getTradingFee(uint256 feeTokenAmount) internal view returns (uint256) {
return feeTokenAmount.mul(tradingFeePercent).divCeil(10**20);
}
Calculate swap external fee.
function _getSwapExternalFee(uint256 feeTokenAmount) internal view
returns(uint256)
Arguments
Name | Type | Description |
---|---|---|
feeTokenAmount | uint256 | The amount of token to swap. |
Returns
The fee of the swap.
Source Code
function _getSwapExternalFee(uint256 feeTokenAmount) internal view returns (uint256) {
return feeTokenAmount.mul(swapExtrernalFeePercent).divCeil(10**20);
}
Calculate the loan origination fee.
function _getBorrowingFee(uint256 feeTokenAmount) internal view
returns(uint256)
Arguments
Name | Type | Description |
---|---|---|
feeTokenAmount | uint256 | The amount of tokens to borrow. |
Returns
The fee of the loan.
Source Code
function _getBorrowingFee(uint256 feeTokenAmount) internal view returns (uint256) {
return feeTokenAmount.mul(borrowingFeePercent).divCeil(10**20);
/*
// p3.9 from bzx peckshield-audit-report-bZxV2-v1.0rc1.pdf
// cannot be applied solely nor with LoanOpenings.sol as it drives to some other tests failure
uint256 collateralAmountRequired =
feeTokenAmount.mul(10**20).divCeil(
10**20 - borrowingFeePercent // never will overflow
);
return collateralAmountRequired.sub(feeTokenAmount);*/
}
Settle the trading fee and pay the token reward to the affiliates referrer. *
function _payTradingFeeToAffiliate(address referrer, address trader, address feeToken, uint256 tradingFee) internal nonpayable
returns(affiliatesBonusSOVAmount uint256, affiliatesBonusTokenAmount uint256)
Arguments
Name | Type | Description |
---|---|---|
referrer | address | The affiliate referrer address to send the reward to. |
trader | address | The account that performs this trade. |
feeToken | address | The address of the token in which the trading fee is paid. |
tradingFee | uint256 | The amount of tokens accrued as fees on the trading. * |
Returns
affiliatesBonusSOVAmount the total SOV amount that is distributed to the referrer
Source Code
function _payTradingFeeToAffiliate(
address referrer,
address trader,
address feeToken,
uint256 tradingFee
) internal returns (uint256 affiliatesBonusSOVAmount, uint256 affiliatesBonusTokenAmount) {
(affiliatesBonusSOVAmount, affiliatesBonusTokenAmount) = ProtocolAffiliatesInterface(
address(this)
)
.payTradingFeeToAffiliatesReferrer(referrer, trader, feeToken, tradingFee);
}
Settle the trading fee and pay the token reward to the user.
function _payTradingFee(address user, bytes32 loanId, address feeToken, address feeTokenPair, uint256 tradingFee) internal nonpayable
Arguments
Name | Type | Description |
---|---|---|
user | address | The address to send the reward to. |
loanId | bytes32 | The Id of the associated loan - used for logging only. |
feeToken | address | The address of the token in which the trading fee is paid. |
feeTokenPair | address | |
tradingFee | uint256 | The amount of tokens accrued as fees on the trading. |
Source Code
function _payTradingFee(
address user,
bytes32 loanId,
address feeToken,
address feeTokenPair,
uint256 tradingFee
) internal {
uint256 protocolTradingFee = tradingFee; /// Trading fee paid to protocol.
if (tradingFee != 0) {
if (affiliatesUserReferrer[user] != address(0)) {
_payTradingFeeToAffiliate(
affiliatesUserReferrer[user],
user,
feeToken,
protocolTradingFee
);
protocolTradingFee = (
protocolTradingFee.sub(protocolTradingFee.mul(affiliateFeePercent).div(10**20))
)
.sub(protocolTradingFee.mul(affiliateTradingTokenFeePercent).div(10**20));
}
/// Increase the storage variable keeping track of the accumulated fees.
tradingFeeTokensHeld[feeToken] = tradingFeeTokensHeld[feeToken].add(
protocolTradingFee
);
emit PayTradingFee(user, feeToken, loanId, protocolTradingFee);
/// Pay the token reward to the user.
_payFeeReward(user, loanId, feeToken, feeTokenPair, tradingFee);
}
}
Settle the borrowing fee and pay the token reward to the user.
function _payBorrowingFee(address user, bytes32 loanId, address feeToken, address feeTokenPair, uint256 borrowingFee) internal nonpayable
Arguments
Name | Type | Description |
---|---|---|
user | address | The address to send the reward to. |
loanId | bytes32 | The Id of the associated loan - used for logging only. |
feeToken | address | The address of the token in which the borrowig fee is paid. |
feeTokenPair | address | |
borrowingFee | uint256 | The height of the fee. |
Source Code
function _payBorrowingFee(
address user,
bytes32 loanId,
address feeToken,
address feeTokenPair,
uint256 borrowingFee
) internal {
if (borrowingFee != 0) {
/// Increase the storage variable keeping track of the accumulated fees.
borrowingFeeTokensHeld[feeToken] = borrowingFeeTokensHeld[feeToken].add(borrowingFee);
emit PayBorrowingFee(user, feeToken, loanId, borrowingFee);
/// Pay the token reward to the user.
_payFeeReward(user, loanId, feeToken, feeTokenPair, borrowingFee);
}
}
Settle the lending fee (based on the interest). Pay no token reward to the user.
function _payLendingFee(address user, address feeToken, uint256 lendingFee) internal nonpayable
Arguments
Name | Type | Description |
---|---|---|
user | address | The address to send the reward to. |
feeToken | address | The address of the token in which the lending fee is paid. |
lendingFee | uint256 | The height of the fee. |
Source Code
function _payLendingFee(
address user,
address feeToken,
uint256 lendingFee
) internal {
if (lendingFee != 0) {
/// Increase the storage variable keeping track of the accumulated fees.
lendingFeeTokensHeld[feeToken] = lendingFeeTokensHeld[feeToken].add(lendingFee);
emit PayLendingFee(user, feeToken, lendingFee);
//// NOTE: Lenders do not receive a fee reward ////
}
}
function _settleFeeRewardForInterestExpense(struct LoanInterestStruct.LoanInterest loanInterestLocal, bytes32 loanId, address feeToken, address feeTokenPair, address user, uint256 interestTime) internal nonpayable
Arguments
Name | Type | Description |
---|---|---|
loanInterestLocal | struct LoanInterestStruct.LoanInterest | |
loanId | bytes32 | |
feeToken | address | |
feeTokenPair | address | |
user | address | |
interestTime | uint256 |
Source Code
function _settleFeeRewardForInterestExpense(
LoanInterest storage loanInterestLocal,
bytes32 loanId,
address feeToken,
address feeTokenPair,
address user,
uint256 interestTime
) internal {
/// This represents the fee generated by a borrower's interest payment.
uint256 interestExpenseFee =
interestTime
.sub(loanInterestLocal.updatedTimestamp)
.mul(loanInterestLocal.owedPerDay)
.mul(lendingFeePercent)
.div(1 days * 10**20);
loanInterestLocal.updatedTimestamp = interestTime;
if (interestExpenseFee != 0) {
_payFeeReward(user, loanId, feeToken, feeTokenPair, interestExpenseFee);
}
}
Pay the potocolToken reward to user. The reward is worth 50% of the trading/borrowing fee.
function _payFeeReward(address user, bytes32 loanId, address feeToken, address feeTokenPair, uint256 feeAmount) internal nonpayable
Arguments
Name | Type | Description |
---|---|---|
user | address | The address to send the reward to. |
loanId | bytes32 | The Id of the associeated loan - used for logging only. |
feeToken | address | The address of the token in which the trading/borrowing fee was paid. |
feeTokenPair | address | |
feeAmount | uint256 | The height of the fee. |
Source Code
function _payFeeReward(
address user,
bytes32 loanId,
address feeToken,
address feeTokenPair,
uint256 feeAmount
) internal {
uint256 rewardAmount;
uint256 _feeRebatePercent = feeRebatePercent;
address _priceFeeds = priceFeeds;
if (specialRebates[feeToken][feeTokenPair] > 0) {
_feeRebatePercent = specialRebates[feeToken][feeTokenPair];
}
/// Note: this should be refactored.
/// Calculate the reward amount, querying the price feed.
(bool success, bytes memory data) =
_priceFeeds.staticcall(
abi.encodeWithSelector(
IPriceFeeds(_priceFeeds).queryReturn.selector,
feeToken,
sovTokenAddress, /// Price rewards using BZRX price rather than vesting token price.
feeAmount.mul(_feeRebatePercent).div(10**20)
)
);
// solhint-disable-next-line no-inline-assembly
assembly {
if eq(success, 1) {
rewardAmount := mload(add(data, 32))
}
}
// Check the dedicated SOV that is used to pay trading rebate rewards
uint256 dedicatedSOV = ISovryn(address(this)).getDedicatedSOVRebate();
if (rewardAmount != 0 && dedicatedSOV >= rewardAmount) {
IERC20(sovTokenAddress).approve(lockedSOVAddress, rewardAmount);
(bool success, ) =
lockedSOVAddress.call(
abi.encodeWithSignature(
"deposit(address,uint256,uint256)",
user,
rewardAmount,
tradingRebateRewardsBasisPoint
)
);
if (success) {
protocolTokenPaid = protocolTokenPaid.add(rewardAmount);
emit EarnReward(
user,
sovTokenAddress,
loanId,
_feeRebatePercent,
rewardAmount,
tradingRebateRewardsBasisPoint
);
} else {
emit EarnRewardFail(
user,
sovTokenAddress,
loanId,
_feeRebatePercent,
rewardAmount,
tradingRebateRewardsBasisPoint
);
}
} else if (rewardAmount != 0 && dedicatedSOV < rewardAmount) {
emit EarnRewardFail(
user,
sovTokenAddress,
loanId,
_feeRebatePercent,
rewardAmount,
tradingRebateRewardsBasisPoint
);
}
}
- Address
- Administered
- AdminRole
- AdvancedToken
- AdvancedTokenStorage
- Affiliates
- AffiliatesEvents
- ApprovalReceiver
- BProPriceFeed
- CheckpointsShared
- Constants
- Context
- DevelopmentFund
- DummyContract
- EnumerableAddressSet
- EnumerableBytes32Set
- EnumerableBytes4Set
- ERC20
- ERC20Detailed
- ErrorDecoder
- Escrow
- EscrowReward
- FeedsLike
- FeesEvents
- FeeSharingCollector
- FeeSharingCollectorProxy
- FeeSharingCollectorStorage
- FeesHelper
- FourYearVesting
- FourYearVestingFactory
- FourYearVestingLogic
- FourYearVestingStorage
- GenericTokenSender
- GovernorAlpha
- GovernorVault
- IApproveAndCall
- IChai
- IContractRegistry
- IConverterAMM
- IERC1820Registry
- IERC20_
- IERC20
- IERC777
- IERC777Recipient
- IERC777Sender
- IFeeSharingCollector
- IFourYearVesting
- IFourYearVestingFactory
- IFunctionsList
- ILiquidityMining
- ILiquidityPoolV1Converter
- ILoanPool
- ILoanToken
- ILoanTokenLogicBeacon
- ILoanTokenLogicModules
- ILoanTokenLogicProxy
- ILoanTokenModules
- ILoanTokenWRBTC
- ILockedSOV
- IMoCState
- IModulesProxyRegistry
- Initializable
- InterestUser
- IPot
- IPriceFeeds
- IPriceFeedsExt
- IProtocol
- IRSKOracle
- ISovryn
- ISovrynSwapNetwork
- IStaking
- ISwapsImpl
- ITeamVesting
- ITimelock
- IV1PoolOracle
- IVesting
- IVestingFactory
- IVestingRegistry
- IWrbtc
- IWrbtcERC20
- LenderInterestStruct
- LiquidationHelper
- LiquidityMining
- LiquidityMiningConfigToken
- LiquidityMiningProxy
- LiquidityMiningStorage
- LoanClosingsEvents
- LoanClosingsLiquidation
- LoanClosingsRollover
- LoanClosingsShared
- LoanClosingsWith
- LoanClosingsWithoutInvariantCheck
- LoanInterestStruct
- LoanMaintenance
- LoanMaintenanceEvents
- LoanOpenings
- LoanOpeningsEvents
- LoanParamsStruct
- LoanSettings
- LoanSettingsEvents
- LoanStruct
- LoanToken
- LoanTokenBase
- LoanTokenLogicBeacon
- LoanTokenLogicLM
- LoanTokenLogicProxy
- LoanTokenLogicStandard
- LoanTokenLogicStorage
- LoanTokenLogicWrbtc
- LoanTokenSettingsLowerAdmin
- LockedSOV
- MarginTradeStructHelpers
- Medianizer
- ModuleCommonFunctionalities
- ModulesCommonEvents
- ModulesProxy
- ModulesProxyRegistry
- MultiSigKeyHolders
- MultiSigWallet
- Mutex
- Objects
- OrderStruct
- OrigingVestingCreator
- OriginInvestorsClaim
- Ownable
- Pausable
- PausableOz
- PreviousLoanToken
- PreviousLoanTokenSettingsLowerAdmin
- PriceFeedRSKOracle
- PriceFeeds
- PriceFeedsLocal
- PriceFeedsMoC
- PriceFeedV1PoolOracle
- ProtocolAffiliatesInterface
- ProtocolLike
- ProtocolSettings
- ProtocolSettingsEvents
- ProtocolSettingsLike
- ProtocolSwapExternalInterface
- ProtocolTokenUser
- Proxy
- ProxyOwnable
- ReentrancyGuard
- RewardHelper
- RSKAddrValidator
- SafeERC20
- SafeMath
- SafeMath96
- setGet
- SharedReentrancyGuard
- SignedSafeMath
- SOV
- sovrynProtocol
- StakingAdminModule
- StakingGovernanceModule
- StakingInterface
- StakingProxy
- StakingRewards
- StakingRewardsProxy
- StakingRewardsStorage
- StakingShared
- StakingStakeModule
- StakingStorageModule
- StakingStorageShared
- StakingVestingModule
- StakingWithdrawModule
- State
- SwapsEvents
- SwapsExternal
- SwapsImplLocal
- SwapsImplSovrynSwap
- SwapsUser
- TeamVesting
- Timelock
- TimelockHarness
- TimelockInterface
- TokenSender
- UpgradableProxy
- USDTPriceFeed
- Utils
- VaultController
- Vesting
- VestingCreator
- VestingFactory
- VestingLogic
- VestingRegistry
- VestingRegistry2
- VestingRegistry3
- VestingRegistryLogic
- VestingRegistryProxy
- VestingRegistryStorage
- VestingStorage
- WeightedStakingModule
- WRBTC