// SPDX-License-Identifier: MITpragmaexperimentalABIEncoderV2;pragmasolidity 0.6.12;import"@openzeppelin/contracts/math/SafeMath.sol";
import"@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import"../libraries/WadRayMath.sol";
import"../interfaces/ISTABLEX.sol";
import"../interfaces/IFeeDistributor.sol";
import"../interfaces/IAddressProvider.sol";
contractFeeDistributorisIFeeDistributor, ReentrancyGuard{
usingSafeMathforuint256;
eventPayeeAdded(address account, uint256 shares);
eventFeeReleased(uint256 income, uint256 releasedAt);
uint256publicoverride lastReleasedAt;
IAddressProvider publicoverride a;
uint256publicoverride totalShares;
mapping(address=>uint256) publicoverride shares;
address[] public payees;
modifieronlyManager() {
require(a.controller().hasRole(a.controller().MANAGER_ROLE(), msg.sender), "Caller is not Manager");
_;
}
constructor(IAddressProvider _addresses) public{
require(address(_addresses) !=address(0));
a = _addresses;
}
/**
Public function to release the accumulated fee income to the payees.
@dev anyone can call this.
*/functionrelease() publicoverridenonReentrant{
uint256 income = a.core().state().availableIncome();
require(income >0, "income is 0");
require(payees.length>0, "Payees not configured yet");
lastReleasedAt =now;
// Mint USDX to all receiversfor (uint256 i =0; i < payees.length; i++) {
address payee = payees[i];
_release(income, payee);
}
emit FeeReleased(income, lastReleasedAt);
}
/**
Updates the payee configuration to a new one.
@dev will release existing fees before the update.
@param _payees Array of payees
@param _shares Array of shares for each payee
*/functionchangePayees(address[] memory _payees, uint256[] memory _shares) publicoverrideonlyManager{
require(_payees.length== _shares.length, "Payees and shares mismatched");
require(_payees.length>0, "No payees");
uint256 income = a.core().state().availableIncome();
if (income >0&& payees.length>0) {
release();
}
for (uint256 i =0; i < payees.length; i++) {
delete shares[payees[i]];
}
delete payees;
totalShares =0;
for (uint256 i =0; i < _payees.length; i++) {
_addPayee(_payees[i], _shares[i]);
}
}
/**
Get current configured payees.
@return array of current payees.
*/functiongetPayees() publicviewoverridereturns (address[] memory) {
return payees;
}
/**
Internal function to release a percentage of income to a specific payee
@dev uses totalShares to calculate correct share
@param _totalIncomeReceived Total income for all payees, will be split according to shares
@param _payee The address of the payee to whom to distribute the fees.
*/function_release(uint256 _totalIncomeReceived, address _payee) internal{
uint256 payment = _totalIncomeReceived.mul(shares[_payee]).div(totalShares);
a.stablex().mint(_payee, payment);
}
/**
Internal function to add a new payee.
@dev will update totalShares and therefore reduce the relative share of all other payees.
@param _payee The address of the payee to add.
@param _shares The number of shares owned by the payee.
*/function_addPayee(address _payee, uint256 _shares) internal{
require(_payee !=address(0), "payee is the zero address");
require(_shares >0, "shares are 0");
require(shares[_payee] ==0, "payee already has shares");
payees.push(_payee);
shares[_payee] = _shares;
totalShares = totalShares.add(_shares);
emit PayeeAdded(_payee, _shares);
}
}
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/interfaceIERC20{
/**
* @dev Returns the amount of tokens in existence.
*/functiontotalSupply() externalviewreturns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/functionbalanceOf(address account) externalviewreturns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/functiontransfer(address recipient, uint256 amount) externalreturns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/functionallowance(address owner, address spender) externalviewreturns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/functionapprove(address spender, uint256 amount) externalreturns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/functiontransferFrom(address sender, address recipient, uint256 amount) externalreturns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/eventTransfer(addressindexedfrom, addressindexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/eventApproval(addressindexed owner, addressindexed spender, uint256 value);
}
// SPDX-License-Identifier: MITpragmaexperimentalABIEncoderV2;pragmasolidity 0.6.12;import"../../interfaces/IAddressProvider.sol";
import"../../governance/interfaces/IGovernanceAddressProvider.sol";
interfaceIGenericMiner{
structUserInfo {
uint256 stake;
uint256 accAmountPerShare; // User's accAmountPerShare
}
/// @dev This emit when a users' productivity has changed/// It emits with the user's address and the the value after the change.eventStakeIncreased(addressindexed user, uint256 stake);
/// @dev This emit when a users' productivity has changed/// It emits with the user's address and the the value after the change.eventStakeDecreased(addressindexed user, uint256 stake);
functionreleaseMIMO(address _user) external;
functiona() externalviewreturns (IGovernanceAddressProvider);
functionstake(address _user) externalviewreturns (uint256);
functionpendingMIMO(address _user) externalviewreturns (uint256);
functiontotalStake() externalviewreturns (uint256);
functionuserInfo(address _user) externalviewreturns (UserInfo memory);
}
// SPDX-License-Identifier: MITpragmaexperimentalABIEncoderV2;pragmasolidity 0.6.12;interfaceIGovernorAlpha{
/// @notice Possible states that a proposal may be inenumProposalState { Active, Canceled, Defeated, Succeeded, Queued, Expired, Executed }
structProposal {
// Unique id for looking up a proposaluint256 id;
// Creator of the proposaladdress proposer;
// The timestamp that the proposal will be available for execution, set once the vote succeedsuint256 eta;
// the ordered list of target addresses for calls to be madeaddress[] targets;
// The ordered list of values (i.e. msg.value) to be passed to the calls to be madeuint256[] values;
// The ordered list of function signatures to be calledstring[] signatures;
// The ordered list of calldata to be passed to each callbytes[] calldatas;
// The timestamp at which voting begins: holders must delegate their votes prior to this timestampuint256 startTime;
// The timestamp at which voting ends: votes must be cast prior to this timestampuint256 endTime;
// Current number of votes in favor of this proposaluint256 forVotes;
// Current number of votes in opposition to this proposaluint256 againstVotes;
// Flag marking whether the proposal has been canceledbool canceled;
// Flag marking whether the proposal has been executedbool executed;
// Receipts of ballots for the entire set of votersmapping(address=> Receipt) receipts;
}
/// @notice Ballot receipt record for a voterstructReceipt {
// Whether or not a vote has been castbool hasVoted;
// Whether or not the voter supports the proposalbool support;
// The number of votes the voter had, which were castuint256 votes;
}
/// @notice An event emitted when a new proposal is createdeventProposalCreated(uint256 id,
address proposer,
address[] targets,
uint256[] values,
string[] signatures,
bytes[] calldatas,
uint256 startTime,
uint256 endTime,
string description
);
/// @notice An event emitted when a vote has been cast on a proposaleventVoteCast(address voter, uint256 proposalId, bool support, uint256 votes);
/// @notice An event emitted when a proposal has been canceledeventProposalCanceled(uint256 id);
/// @notice An event emitted when a proposal has been queued in the TimelockeventProposalQueued(uint256 id, uint256 eta);
/// @notice An event emitted when a proposal has been executed in the TimelockeventProposalExecuted(uint256 id);
functionpropose(address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas,
stringmemory description,
uint256 endTime
) externalreturns (uint256);
functionqueue(uint256 proposalId) external;
functionexecute(uint256 proposalId) externalpayable;
functioncancel(uint256 proposalId) external;
functioncastVote(uint256 proposalId, bool support) external;
functiongetActions(uint256 proposalId)
externalviewreturns (address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas
);
functiongetReceipt(uint256 proposalId, address voter) externalviewreturns (Receipt memory);
functionstate(uint256 proposalId) externalviewreturns (ProposalState);
functionquorumVotes() externalviewreturns (uint256);
functionproposalThreshold() externalviewreturns (uint256);
}
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/abstractcontractReentrancyGuard{
// Booleans are more expensive than uint256 or any type that takes up a full// word because each write operation emits an extra SLOAD to first read the// slot's contents, replace the bits taken up by the boolean, and then write// back. This is the compiler's defense against contract upgrades and// pointer aliasing, and it cannot be disabled.// The values being non-zero value makes deployment a bit more expensive,// but in exchange the refund on every call to nonReentrant will be lower in// amount. Since refunds are capped to a percentage of the total// transaction's gas, it is best to keep them low in cases like this one, to// increase the likelihood of the full refund coming into effect.uint256privateconstant _NOT_ENTERED =1;
uint256privateconstant _ENTERED =2;
uint256private _status;
constructor () internal{
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and make it call a
* `private` function that does the actual work.
*/modifiernonReentrant() {
// On the first call to nonReentrant, _notEntered will be truerequire(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}
Contract Source Code
File 29 of 30: SafeMath.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/librarySafeMath{
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/functiontryAdd(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/functiontrySub(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/functiontryMul(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the// benefit is lost if 'b' is also tested.// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522if (a ==0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/functiontryDiv(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
if (b ==0) return (false, 0);
return (true, a / b);
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/functiontryMod(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
if (b ==0) return (false, 0);
return (true, a % b);
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/functionadd(uint256 a, uint256 b) internalpurereturns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/functionsub(uint256 a, uint256 b) internalpurereturns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/functionmul(uint256 a, uint256 b) internalpurereturns (uint256) {
if (a ==0) return0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functiondiv(uint256 a, uint256 b) internalpurereturns (uint256) {
require(b >0, "SafeMath: division by zero");
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functionmod(uint256 a, uint256 b) internalpurereturns (uint256) {
require(b >0, "SafeMath: modulo by zero");
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/functionsub(uint256 a, uint256 b, stringmemory errorMessage) internalpurereturns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryDiv}.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functiondiv(uint256 a, uint256 b, stringmemory errorMessage) internalpurereturns (uint256) {
require(b >0, errorMessage);
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functionmod(uint256 a, uint256 b, stringmemory errorMessage) internalpurereturns (uint256) {
require(b >0, errorMessage);
return a % b;
}
}
Contract Source Code
File 30 of 30: WadRayMath.sol
// SPDX-License-Identifier: MITpragmasolidity 0.6.12;import"@openzeppelin/contracts/math/SafeMath.sol";
/******************
@title WadRayMath library
@author Aave
@dev Provides mul and div function for wads (decimal numbers with 18 digits precision) and rays (decimals with 27 digits)
*/libraryWadRayMath{
usingSafeMathforuint256;
uint256internalconstant _WAD =1e18;
uint256internalconstant _HALF_WAD = _WAD /2;
uint256internalconstant _RAY =1e27;
uint256internalconstant _HALF_RAY = _RAY /2;
uint256internalconstant _WAD_RAY_RATIO =1e9;
functionray() internalpurereturns (uint256) {
return _RAY;
}
functionwad() internalpurereturns (uint256) {
return _WAD;
}
functionhalfRay() internalpurereturns (uint256) {
return _HALF_RAY;
}
functionhalfWad() internalpurereturns (uint256) {
return _HALF_WAD;
}
functionwadMul(uint256 a, uint256 b) internalpurereturns (uint256) {
return _HALF_WAD.add(a.mul(b)).div(_WAD);
}
functionwadDiv(uint256 a, uint256 b) internalpurereturns (uint256) {
uint256 halfB = b /2;
return halfB.add(a.mul(_WAD)).div(b);
}
functionrayMul(uint256 a, uint256 b) internalpurereturns (uint256) {
return _HALF_RAY.add(a.mul(b)).div(_RAY);
}
functionrayDiv(uint256 a, uint256 b) internalpurereturns (uint256) {
uint256 halfB = b /2;
return halfB.add(a.mul(_RAY)).div(b);
}
functionrayToWad(uint256 a) internalpurereturns (uint256) {
uint256 halfRatio = _WAD_RAY_RATIO /2;
return halfRatio.add(a).div(_WAD_RAY_RATIO);
}
functionwadToRay(uint256 a) internalpurereturns (uint256) {
return a.mul(_WAD_RAY_RATIO);
}
/**
* @dev calculates x^n, in ray. The code uses the ModExp precompile
* @param x base
* @param n exponent
* @return z = x^n, in ray
*/functionrayPow(uint256 x, uint256 n) internalpurereturns (uint256 z) {
z = n %2!=0 ? x : _RAY;
for (n /=2; n !=0; n /=2) {
x = rayMul(x, x);
if (n %2!=0) {
z = rayMul(z, x);
}
}
}
}