Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- WeightAggregator
- Optimization enabled
- true
- Compiler version
- v0.8.17+commit.8df45f5f
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2024-06-02T14:00:56.433126Z
Constructor Arguments
0x0000000000000000000000002597ba2385be4d2e49aad864c377378736b680d1000000000000000000000000a59512c9471912f99958b867f6954f5bef0cb3f4000000000000000000000000fdc8c1c2352a813d902a596e8597f7215dd15087
Arg [0] (address) : 0x2597ba2385be4d2e49aad864c377378736b680d1
Arg [1] (address) : 0xa59512c9471912f99958b867f6954f5bef0cb3f4
Arg [2] (address) : 0xfdc8c1c2352a813d902a596e8597f7215dd15087
contracts/WeightAggregator.sol
// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.17; import "./interfaces/IWeightAggregator.sol"; import "./interfaces/IBuyback.sol"; import "./interfaces/IVesting.sol"; import "./interfaces/IRewardsHub.sol"; contract WeightAggregator is IWeightAggregator { uint256 internal constant LOYALTY_SCALE = 1e18; IBuyback public immutable buyback; IVesting public immutable vesting; IRewardsHub public immutable rewardsHub; constructor( IBuyback buyback_, IVesting vesting_, IRewardsHub rewardsHub_ ) { buyback = buyback_; vesting = vesting_; rewardsHub = rewardsHub_; } /// @inheritdoc IWeightAggregator function getAccountFunds(address account) public view returns (uint256) { return buyback.getStakedAmount(account) + vesting.releasableAmount(account) + rewardsHub.availableBalanceOf(account); } function getLoyaltyFactor(address account) external view returns (uint256) { return buyback.getLoyaltyFactorForBalance(account, getAccountFunds(account)); } /// @inheritdoc IWeightAggregator function getBuybackWeight(address account) external view returns (uint256) { if (!buyback.isParticipating(account)) return 0; uint256 funds = getAccountFunds(account); uint256 loyaltyFactor = buyback.getLoyaltyFactorForBalance(account, funds); return funds + (funds * loyaltyFactor) / LOYALTY_SCALE; } /// @inheritdoc IWeightAggregator function getVotingWeight(address account) external view returns (uint256) { if (!buyback.isParticipating(account)) return 0; uint256 funds = getAccountFunds(account); uint256 loyaltyFactor = buyback.getLoyaltyFactorForBalance(account, funds); uint256 votes = buyback.getStakedAmount(account) + vesting.getReleasableWithoutCliff(account) + rewardsHub.totalBalanceOf(account); return votes + (votes * loyaltyFactor) / LOYALTY_SCALE; } }
contracts/interfaces/IRewardsHub.sol
// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.17; import "./IRewardsHubLight.sol"; interface IRewardsHub is IRewardsHubLight { event RewardUnlocked(address account, uint256 amount); /** * @notice Gets summary amount of available and delayed balances of an account. */ function totalBalanceOf(address account) external view override returns (uint256); /** * @notice Gets part of delayed rewards that is unlocked and have become available. */ function getUnlockableRewards(address account) external view returns (uint256); }
@openzeppelin/contracts/access/IAccessControl.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
contracts/interfaces/IMToken.sol
// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.17; import "@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import "@openzeppelin/contracts/access/IAccessControl.sol"; import "./IInterestRateModel.sol"; interface IMToken is IAccessControl, IERC20, IERC3156FlashLender, IERC165 { /** * @notice Event emitted when interest is accrued */ event AccrueInterest( uint256 cashPrior, uint256 interestAccumulated, uint256 borrowIndex, uint256 totalBorrows, uint256 totalProtocolInterest ); /** * @notice Event emitted when tokens are lended */ event Lend(address lender, uint256 lendAmount, uint256 lendTokens, uint256 newTotalTokenSupply); /** * @notice Event emitted when tokens are redeemed */ event Redeem(address redeemer, uint256 redeemAmount, uint256 redeemTokens, uint256 newTotalTokenSupply); /** * @notice Event emitted when underlying is borrowed */ event Borrow(address borrower, uint256 borrowAmount, uint256 accountBorrows, uint256 totalBorrows); /** * @notice Event emitted when tokens are seized */ event Seize( address borrower, address receiver, uint256 seizeTokens, uint256 accountsTokens, uint256 totalSupply, uint256 seizeUnderlyingAmount ); /** * @notice Event emitted when a borrow is repaid */ event RepayBorrow( address payer, address borrower, uint256 repayAmount, uint256 accountBorrows, uint256 totalBorrows ); /** * @notice Event emitted when a borrow is repaid during autoliquidation */ event AutoLiquidationRepayBorrow( address borrower, uint256 repayAmount, uint256 accountBorrowsNew, uint256 totalBorrowsNew, uint256 TotalProtocolInterestNew ); /** * @notice Event emitted when flash loan is executed */ event FlashLoanExecuted(address receiver, uint256 amount, uint256 fee); /** * @notice Event emitted when interestRateModel is changed */ event NewMarketInterestRateModel(IInterestRateModel oldInterestRateModel, IInterestRateModel newInterestRateModel); /** * @notice Event emitted when the protocol interest factor is changed */ event NewProtocolInterestFactor( uint256 oldProtocolInterestFactorMantissa, uint256 newProtocolInterestFactorMantissa ); /** * @notice Event emitted when the flash loan max share is changed */ event NewFlashLoanMaxShare(uint256 oldMaxShare, uint256 newMaxShare); /** * @notice Event emitted when the flash loan fee is changed */ event NewFlashLoanFee(uint256 oldFee, uint256 newFee); /** * @notice Event emitted when the protocol interest are added */ event ProtocolInterestAdded(address benefactor, uint256 addAmount, uint256 newTotalProtocolInterest); /** * @notice Event emitted when the protocol interest reduced */ event ProtocolInterestReduced(address admin, uint256 reduceAmount, uint256 newTotalProtocolInterest); /** * @notice Value is the Keccak-256 hash of "TIMELOCK" */ function TIMELOCK() external view returns (bytes32); /** * @notice Underlying asset for this MToken */ function underlying() external view returns (IERC20); /** * @notice EIP-20 token name for this token */ function name() external view returns (string memory); /** * @notice EIP-20 token symbol for this token */ function symbol() external view returns (string memory); /** * @notice EIP-20 token decimals for this token */ function decimals() external view returns (uint8); /** * @notice Model which tells what the current interest rate should be */ function interestRateModel() external view returns (IInterestRateModel); /** * @notice Initial exchange rate used when lending the first MTokens (used when totalTokenSupply = 0) */ function initialExchangeRateMantissa() external view returns (uint256); /** * @notice Fraction of interest currently set aside for protocol interest */ function protocolInterestFactorMantissa() external view returns (uint256); /** * @notice Block number that interest was last accrued at */ function accrualBlockNumber() external view returns (uint256); /** * @notice Accumulator of the total earned interest rate since the opening of the market */ function borrowIndex() external view returns (uint256); /** * @notice Total amount of outstanding borrows of the underlying in this market */ function totalBorrows() external view returns (uint256); /** * @notice Total amount of protocol interest of the underlying held in this market */ function totalProtocolInterest() external view returns (uint256); /** * @notice Share of market's current underlying token balance that can be used as flash loan (scaled by 1e18). */ function maxFlashLoanShare() external view returns (uint256); /** * @notice Share of flash loan amount that would be taken as fee (scaled by 1e18). */ function flashLoanFeeShare() external view returns (uint256); /** * @notice Returns total token supply */ function totalSupply() external view returns (uint256); /** * @notice Transfer `amount` tokens from `msg.sender` to `dst` * @param dst The address of the destination account * @param amount The number of tokens to transfer * @return Whether or not the transfer succeeded */ function transfer(address dst, uint256 amount) external returns (bool); /** * @notice Transfer `amount` tokens from `src` to `dst` * @param src The address of the source account * @param dst The address of the destination account * @param amount The number of tokens to transfer * @return Whether or not the transfer succeeded */ function transferFrom( address src, address dst, uint256 amount ) external returns (bool); /** * @notice Approve `spender` to transfer up to `amount` from `src` * @dev This will overwrite the approval amount for `spender` * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve) * @param spender The address of the account which may transfer tokens * @param amount The number of tokens that are approved (-1 means infinite) * @return Whether or not the approval succeeded */ function approve(address spender, uint256 amount) external returns (bool); /** * @notice Get the current allowance from `owner` for `spender` * @param owner The address of the account which owns the tokens to be spent * @param spender The address of the account which may transfer tokens * @return The number of tokens allowed to be spent (-1 means infinite) */ function allowance(address owner, address spender) external view returns (uint256); /** * @notice Get the token balance of the `owner` * @param owner The address of the account to query * @return The number of tokens owned by `owner` */ function balanceOf(address owner) external view returns (uint256); /** * @notice Get the underlying balance of the `owner` * @dev This also accrues interest in a transaction * @param owner The address of the account to query * @return The amount of underlying owned by `owner` */ function balanceOfUnderlying(address owner) external returns (uint256); /** * @notice Get a snapshot of the account's balances, and the cached exchange rate * @dev This is used by supervisor to more efficiently perform liquidity checks. * @param account Address of the account to snapshot * @return (token balance, borrow balance, exchange rate mantissa) */ function getAccountSnapshot(address account) external view returns ( uint256, uint256, uint256 ); /** * @notice Returns the current per-block borrow interest rate for this mToken * @return The borrow interest rate per block, scaled by 1e18 */ function borrowRatePerBlock() external view returns (uint256); /** * @notice Returns the current per-block supply interest rate for this mToken * @return The supply interest rate per block, scaled by 1e18 */ function supplyRatePerBlock() external view returns (uint256); /** * @notice Returns the current total borrows plus accrued interest * @return The total borrows with interest */ function totalBorrowsCurrent() external returns (uint256); /** * @notice Accrue interest to updated borrowIndex and then calculate account's * borrow balance using the updated borrowIndex * @param account The address whose balance should be calculated after updating borrowIndex * @return The calculated balance */ function borrowBalanceCurrent(address account) external returns (uint256); /** * @notice Return the borrow balance of account based on stored data * @param account The address whose balance should be calculated * @return The calculated balance */ function borrowBalanceStored(address account) external view returns (uint256); /** * @notice Accrue interest then return the up-to-date exchange rate * @return Calculated exchange rate scaled by 1e18 */ function exchangeRateCurrent() external returns (uint256); /** * @notice Calculates the exchange rate from the underlying to the MToken * @dev This function does not accrue interest before calculating the exchange rate * @return Calculated exchange rate scaled by 1e18 */ function exchangeRateStored() external view returns (uint256); /** * @notice Get cash balance of this mToken in the underlying asset * @return The quantity of underlying asset owned by this contract */ function getCash() external view returns (uint256); /** * @notice Applies accrued interest to total borrows and protocol interest * @dev This calculates interest accrued from the last checkpointed block * up to the current block and writes new checkpoint to storage. */ function accrueInterest() external; /** * @notice Sender supplies assets into the market and receives mTokens in exchange * @dev Accrues interest whether or not the operation succeeds, unless reverted * @param lendAmount The amount of the underlying asset to supply */ function lend(uint256 lendAmount) external; /** * @notice Sender redeems mTokens in exchange for the underlying asset * @dev Accrues interest whether or not the operation succeeds, unless reverted * @param redeemTokens The number of mTokens to redeem into underlying */ function redeem(uint256 redeemTokens) external; /** * @notice Redeems all mTokens for account in exchange for the underlying asset. * Can only be called within the AML system! * @dev Accrues interest whether or not the operation succeeds, unless reverted * @param account An account that is potentially sanctioned by the AML system */ function redeemByAmlDecision(address account) external; /** * @notice Sender redeems mTokens in exchange for a specified amount of underlying asset * @dev Accrues interest whether or not the operation succeeds, unless reverted * @param redeemAmount The amount of underlying to receive from redeeming mTokens */ function redeemUnderlying(uint256 redeemAmount) external; /** * @notice Sender borrows assets from the protocol to their own address * @param borrowAmount The amount of the underlying asset to borrow */ function borrow(uint256 borrowAmount) external; /** * @notice Sender repays their own borrow * @param repayAmount The amount to repay */ function repayBorrow(uint256 repayAmount) external; /** * @notice Sender repays a borrow belonging to borrower * @param borrower the account with the debt being payed off * @param repayAmount The amount to repay */ function repayBorrowBehalf(address borrower, uint256 repayAmount) external; /** * @notice Liquidator repays a borrow belonging to borrower * @param borrower_ the account with the debt being payed off * @param repayAmount_ the amount of underlying tokens being returned */ function autoLiquidationRepayBorrow(address borrower_, uint256 repayAmount_) external; /** * @notice A public function to sweep accidental ERC-20 transfers to this contract. * Tokens are sent to admin (timelock) * @param token The address of the ERC-20 token to sweep * @dev RESTRICTION: Admin only. */ function sweepToken(IERC20 token, address admin_) external; /** * @notice Burns collateral tokens at the borrower's address, transfer underlying assets to the Liquidator address. * @dev Called only during an auto liquidation process, msg.sender must be the Liquidation contract. * @param borrower_ The account having collateral seized * @param seizeUnderlyingAmount_ The number of underlying assets to seize. The caller must ensure that the parameter is greater than zero. * @param isLoanInsignificant_ Marker for insignificant loan whose collateral must be credited to the protocolInterest * @param receiver_ Address that receives accounts collateral */ function autoLiquidationSeize( address borrower_, uint256 seizeUnderlyingAmount_, bool isLoanInsignificant_, address receiver_ ) external; /** * @notice The amount of currency available to be lent. * @param token The loan currency. * @return The amount of `token` that can be borrowed. */ function maxFlashLoan(address token) external view returns (uint256); /** * @notice The fee to be charged for a given loan. * @param token The loan currency. * @param amount The amount of tokens lent. * @return The amount of `token` to be charged for the loan, on top of the returned principal. */ function flashFee(address token, uint256 amount) external view returns (uint256); /** * @notice Initiate a flash loan. * @param receiver The receiver of the tokens in the loan, and the receiver of the callback. * @param token The loan currency. * @param amount The amount of tokens lent. * @param data Arbitrary data structure, intended to contain user-defined parameters. */ function flashLoan( IERC3156FlashBorrower receiver, address token, uint256 amount, bytes calldata data ) external returns (bool); /** * @notice accrues interest and sets a new protocol interest factor for the protocol * @dev Admin function to accrue interest and set a new protocol interest factor * @dev RESTRICTION: Timelock only. */ function setProtocolInterestFactor(uint256 newProtocolInterestFactorMantissa) external; /** * @notice Accrues interest and increase protocol interest by transferring from msg.sender * @param addAmount_ Amount of addition to protocol interest */ function addProtocolInterest(uint256 addAmount_) external; /** * @notice Can only be called by liquidation contract. Increase protocol interest by transferring from payer. * @dev Calling code should make sure that accrueInterest() was called before. * @param payer_ The address from which the protocol interest will be transferred * @param addAmount_ Amount of addition to protocol interest */ function addProtocolInterestBehalf(address payer_, uint256 addAmount_) external; /** * @notice Accrues interest and reduces protocol interest by transferring to admin * @param reduceAmount Amount of reduction to protocol interest * @dev RESTRICTION: Admin only. */ function reduceProtocolInterest(uint256 reduceAmount, address admin_) external; /** * @notice accrues interest and updates the interest rate model using setInterestRateModelFresh * @dev Admin function to accrue interest and update the interest rate model * @param newInterestRateModel the new interest rate model to use * @dev RESTRICTION: Timelock only. */ function setInterestRateModel(IInterestRateModel newInterestRateModel) external; /** * @notice Updates share of markets cash that can be used as maximum amount of flash loan. * @param newMax New max amount share * @dev RESTRICTION: Timelock only. */ function setFlashLoanMaxShare(uint256 newMax) external; /** * @notice Updates fee of flash loan. * @param newFee New fee share of flash loan * @dev RESTRICTION: Timelock only. */ function setFlashLoanFeeShare(uint256 newFee) external; }
@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC3156FlashBorrower.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC3156 FlashBorrower, as defined in * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156]. * * _Available since v4.1._ */ interface IERC3156FlashBorrower { /** * @dev Receive a flash loan. * @param initiator The initiator of the loan. * @param token The loan currency. * @param amount The amount of tokens lent. * @param fee The additional amount of tokens to repay. * @param data Arbitrary data structure, intended to contain user-defined parameters. * @return The keccak256 hash of "ERC3156FlashBorrower.onFlashLoan" */ function onFlashLoan( address initiator, address token, uint256 amount, uint256 fee, bytes calldata data ) external returns (bytes32); }
@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156FlashLender.sol) pragma solidity ^0.8.0; import "./IERC3156FlashBorrower.sol"; /** * @dev Interface of the ERC3156 FlashLender, as defined in * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156]. * * _Available since v4.1._ */ interface IERC3156FlashLender { /** * @dev The amount of currency available to be lended. * @param token The loan currency. * @return The amount of `token` that can be borrowed. */ function maxFlashLoan(address token) external view returns (uint256); /** * @dev The fee to be charged for a given loan. * @param token The loan currency. * @param amount The amount of tokens lent. * @return The amount of `token` to be charged for the loan, on top of the returned principal. */ function flashFee(address token, uint256 amount) external view returns (uint256); /** * @dev Initiate a flash loan. * @param receiver The receiver of the tokens in the loan, and the receiver of the callback. * @param token The loan currency. * @param amount The amount of tokens lent. * @param data Arbitrary data structure, intended to contain user-defined parameters. */ function flashLoan( IERC3156FlashBorrower receiver, address token, uint256 amount, bytes calldata data ) external returns (bool); }
@openzeppelin/contracts/token/ERC20/IERC20.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed 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. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (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. */ function allowance(address owner, address spender) external view returns (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. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` 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. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
@openzeppelin/contracts/utils/introspection/IERC165.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
contracts/interfaces/IBuyback.sol
// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.17; import "@openzeppelin/contracts/access/IAccessControl.sol"; import "./ILinkageLeaf.sol"; interface IBuyback is IAccessControl, ILinkageLeaf { event Stake(address who, uint256 amount); event Unstake(address who, uint256 amount); event NewBuyback(uint256 amount, uint256 share); event ParticipateBuyback(address who); event LeaveBuyback(address who, uint256 currentStaked); event BuybackWeightChanged(address who, uint256 newWeight, uint256 oldWeight, uint256 newTotalWeight); event LoyaltyParametersChanged(uint256 newCoreFactor, uint32 newCoreResetPenalty); event LoyaltyStrataChanged(); event LoyaltyGroupsChanged(uint256 newGroupCount); /** * @notice Gets info about account membership in Buyback */ function getMemberInfo(address account) external view returns ( bool participating, uint256 weight, uint256 lastIndex, uint256 stakeAmount ); /** * @notice Gets info about accounts loyalty calculation */ function getLoyaltyInfo(address account) external view returns ( uint32 loyaltyStart, uint256 coreBalance, uint256 lastBalance ); /** * @notice Gets if an account is participating in Buyback */ function isParticipating(address account) external view returns (bool); /** * @notice Gets stake of the account */ function getStakedAmount(address account) external view returns (uint256); /** * @notice Gets buyback weight of an account */ function getWeight(address account) external view returns (uint256); /** * @notice Gets loyalty factor of an account with given balance. */ function getLoyaltyFactorForBalance(address account, uint256 balance) external view returns (uint256); /** * @notice Gets total Buyback weight, which is the sum of weights of all accounts. */ function getTotalWeight() external view returns (uint256); /** * @notice Gets current Buyback index. * Its the accumulated sum of MNTs shares that are given for each weight of an account. */ function getBuybackIndex() external view returns (uint256); /** * @notice Gets all global loyalty parameters. */ function getLoyaltyParameters() external view returns ( uint256[24] memory loyaltyStrata, uint256[] memory groupThresholds, uint32[] memory groupStartStrata, uint256 coreFactor, uint32 coreResetPenalty ); /** * @notice Stakes the specified amount of MNT and transfers them to this contract. * @notice This contract should be approved to transfer MNT from sender account * @param amount The amount of MNT to stake */ function stake(uint256 amount) external; /** * @notice Unstakes the specified amount of MNT and transfers them back to sender if he participates * in the Buyback system, otherwise just transfers MNT tokens to the sender. * would not be greater than staked amount left. If `amount == MaxUint256` unstakes all staked tokens. * @param amount The amount of MNT to unstake */ function unstake(uint256 amount) external; /** * @notice Claims buyback rewards, updates buyback weight and voting power. * Does nothing if account is not participating. Reverts if operation is paused. * @param account Address to update weights for */ function updateBuybackAndVotingWeights(address account) external; /** * @notice Claims buyback rewards, updates buyback weight and voting power. * Does nothing if account is not participating or update is paused. * @param account Address to update weights for */ function updateBuybackAndVotingWeightsRelaxed(address account) external; /** * @notice Does a buyback using the specified amount of MNT from sender's account * @param amount The amount of MNT to take and distribute as buyback * @dev RESTRICTION: Distributor only */ function buyback(uint256 amount) external; /** * @notice Make account participating in the buyback. */ function participate() external; /** * @notice Make accounts participate in buyback before its start. * @param accounts Address to make participate in buyback. * @dev RESTRICTION: Admin only */ function participateOnBehalf(address[] memory accounts) external; /** * @notice Leave buyback participation, claim any MNTs rewarded by the buyback. * Leaving does not withdraw staked MNTs but reduces weight of the account to zero */ function leave() external; /** * @notice Leave buyback participation on behalf, claim any MNTs rewarded by the buyback and * reduce the weight of account to zero. All staked MNTs remain on the buyback contract and available * for their owner to be claimed * Can only be called if (timestamp > participantLastVoteTimestamp + maxNonVotingPeriod). * @param participant Address to leave for * @dev RESTRICTION: GATEKEEPER only */ function leaveOnBehalf(address participant) external; /** * @notice Leave buyback participation on behalf, claim any MNTs rewarded by the buyback and * reduce the weight of account to zero. All staked MNTs remain on the buyback contract and available * for their owner to be claimed. * @dev Function to leave sanctioned accounts from Buyback system * Can only be called if the participant is sanctioned by the AML system. * @param participant Address to leave for */ function leaveByAmlDecision(address participant) external; /** * @notice Changes loyalty core factor and core reset penalty parameters. * @dev RESTRICTION: Admin only */ function setLoyaltyParameters(uint256 newCoreFactor, uint32 newCoreResetPenalty) external; /** * @notice Sets new loyalty factors for all strata. * @dev RESTRICTION: Admin only */ function setLoyaltyStrata(uint256[24] memory newLoyaltyStrata) external; /** * @notice Sets new groups and their parameters * @param newGroupThresholds New list of groups and their balance thresholds. * @param newGroupStartStrata Indexes of starting stratum of each group. First index MUST be zero. * Length of array must be equal to the newGroupThresholds * @dev RESTRICTION: Admin only */ function setLoyaltyGroups(uint256[] memory newGroupThresholds, uint32[] memory newGroupStartStrata) external; }
contracts/interfaces/IInterestRateModel.sol
// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.17; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; /** * @title Minterest InterestRateModel Interface * @author Minterest */ interface IInterestRateModel { /** * @notice Calculates the current borrow interest rate per block * @param cash The total amount of cash the market has * @param borrows The total amount of borrows the market has outstanding * @param protocolInterest The total amount of protocol interest the market has * @return The borrow rate per block (as a percentage, and scaled by 1e18) */ function getBorrowRate( uint256 cash, uint256 borrows, uint256 protocolInterest ) external view returns (uint256); /** * @notice Calculates the current supply interest rate per block * @param cash The total amount of cash the market has * @param borrows The total amount of borrows the market has outstanding * @param protocolInterest The total amount of protocol interest the market has * @param protocolInterestFactorMantissa The current protocol interest factor the market has * @return The supply rate per block (as a percentage, and scaled by 1e18) */ function getSupplyRate( uint256 cash, uint256 borrows, uint256 protocolInterest, uint256 protocolInterestFactorMantissa ) external view returns (uint256); }
contracts/interfaces/ILinkageLeaf.sol
// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.17; import "./ILinkageRoot.sol"; interface ILinkageLeaf { /** * @notice Emitted when root contract address is changed */ event LinkageRootSwitched(ILinkageRoot newRoot, ILinkageRoot oldRoot); /** * @notice Connects new root contract address * @param newRoot New root contract address */ function switchLinkageRoot(ILinkageRoot newRoot) external; }
contracts/interfaces/ILinkageRoot.sol
// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.17; interface ILinkageRoot { /** * @notice Emitted when new root contract connected to all leafs */ event LinkageRootSwitch(ILinkageRoot newRoot); /** * @notice Emitted when root interconnects its contracts */ event LinkageRootInterconnected(); /** * @notice Connects new root to all leafs contracts * @param newRoot New root contract address */ function switchLinkageRoot(ILinkageRoot newRoot) external; /** * @notice Update root for all leaf contracts * @dev Should include only leaf contracts */ function interconnect() external; }
contracts/interfaces/IRewardsHubLight.sol
// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.17; import "./IMToken.sol"; import "./ILinkageLeaf.sol"; interface IRewardsHubLight is ILinkageLeaf { event DistributedSupplierMnt(IMToken mToken, address supplier, uint256 mntDelta, uint256 mntSupplyIndex); event DistributedBorrowerMnt(IMToken mToken, address borrower, uint256 mntDelta, uint256 mntBorrowIndex); event EmissionRewardAccrued(address account, uint256 amount); event RepresentativeRewardAccrued(address account, address provider, uint256 amount); event BuybackRewardAccrued(address account, uint256 amount); event Withdraw(address account, uint256 amount); event MntGranted(address recipient, uint256 amount); event MntSupplyEmissionRateUpdated(IMToken mToken, uint256 newSupplyEmissionRate); event MntBorrowEmissionRateUpdated(IMToken mToken, uint256 newBorrowEmissionRate); /** * @notice get keccak-256 hash of gatekeeper */ function GATEKEEPER() external view returns (bytes32); /** * @notice get keccak-256 hash of timelock */ function TIMELOCK() external view returns (bytes32); /** * @notice Gets the rate at which MNT is distributed to the corresponding supply market (per block) */ function mntSupplyEmissionRate(IMToken) external view returns (uint256); /** * @notice Gets the rate at which MNT is distributed to the corresponding borrow market (per block) */ function mntBorrowEmissionRate(IMToken) external view returns (uint256); /** * @notice Gets the MNT market supply state for each market */ function mntSupplyState(IMToken) external view returns (uint224 index, uint32 blockN); /** * @notice Gets the MNT market borrow state for each market */ function mntBorrowState(IMToken) external view returns (uint224 index, uint32 blockN); /** * @notice Gets the MNT supply index and block number for each market */ function mntSupplierState(IMToken, address) external view returns (uint224 index, uint32 blockN); /** * @notice Gets the MNT borrow index and block number for each market */ function mntBorrowerState(IMToken, address) external view returns (uint224 index, uint32 blockN); /** * @notice Gets amount of available balance of an account. */ function totalBalanceOf(address account) external view returns (uint256); /** * @notice Gets amount of MNT that can be withdrawn from an account at this block. */ function availableBalanceOf(address account) external view returns (uint256); /** * @notice Initializes market in RewardsHub. Should be called once from Supervisor.supportMarket * @dev RESTRICTION: Supervisor only */ function initMarket(IMToken mToken) external; /** * @notice Accrues MNT to the market by updating the borrow and supply indexes * @dev This method doesn't update MNT index history in Minterest NFT. * @param market The market whose supply and borrow index to update * @return (MNT supply index, MNT borrow index) */ function updateAndGetMntIndexes(IMToken market) external returns (uint224, uint224); /** * @notice Shorthand function to distribute MNT emissions from supplies of one market. */ function distributeSupplierMnt(IMToken mToken, address account) external; /** * @notice Shorthand function to distribute MNT emissions from borrows of one market. */ function distributeBorrowerMnt(IMToken mToken, address account) external; /** * @notice Updates market indexes and distributes tokens (if any) for holder * @dev Updates indexes and distributes only for those markets where the holder have a * non-zero supply or borrow balance. * @param account The address to distribute MNT for */ function distributeAllMnt(address account) external; /** * @notice Distribute all MNT accrued by the accounts * @param accounts The addresses to distribute MNT for * @param mTokens The list of markets to distribute MNT in * @param borrowers Whether or not to distribute MNT earned by borrowing * @param suppliers Whether or not to distribute MNT earned by supplying */ function distributeMnt( address[] memory accounts, IMToken[] memory mTokens, bool borrowers, bool suppliers ) external; /** * @notice Accrues buyback reward * @dev RESTRICTION: Buyback only */ function accrueBuybackReward(address account, uint256 amount) external; /** * @notice Transfers available part of MNT rewards to the sender. * This will decrease accounts buyback and voting weights. */ function withdraw(uint256 amount) external; /** * @notice Transfers * @dev RESTRICTION: Admin only */ function grant(address recipient, uint256 amount) external; /** * @notice Set MNT borrow and supply emission rates for a single market * @param mToken The market whose MNT emission rate to update * @param newMntSupplyEmissionRate New supply MNT emission rate for market * @param newMntBorrowEmissionRate New borrow MNT emission rate for market * @dev RESTRICTION Timelock only */ function setMntEmissionRates( IMToken mToken, uint256 newMntSupplyEmissionRate, uint256 newMntBorrowEmissionRate ) external; }
contracts/interfaces/IVesting.sol
// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.17; import "@openzeppelin/contracts/access/IAccessControl.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./IBuyback.sol"; /** * @title Vesting contract provides unlocking of tokens on a schedule. It uses the *graded vesting* way, * which unlocks a specific amount of balance every period of time, until all balance unlocked. * * Vesting Schedule. * * The schedule of a vesting is described by data structure `VestingSchedule`: starting from the start timestamp * throughout the duration, the entire amount of totalAmount tokens will be unlocked. */ interface IVesting is IAccessControl { /** * @notice An event that's emitted when a new vesting schedule for a account is created. */ event VestingScheduleAdded(address target, VestingSchedule schedule); /** * @notice An event that's emitted when a vesting schedule revoked. */ event VestingScheduleRevoked(address target, uint256 unreleased, uint256 locked); /** * @notice An event that's emitted when the account Withdrawn the released tokens. */ event Withdrawn(address target, uint256 withdrawn); /** * @notice Emitted when an account is added to the delay list */ event AddedToDelayList(address account); /** * @notice Emitted when an account is removed from the delay list */ event RemovedFromDelayList(address account); /** * @notice The structure is used in the contract constructor for create vesting schedules * during contract deploying. * @param totalAmount the number of tokens to be vested during the vesting duration. * @param target the address that will receive tokens according to schedule parameters. * @param start offset in minutes at which vesting starts. Zero will vesting immediately. * @param duration duration in minutes of the period in which the tokens will vest. * @param revocable whether the vesting is revocable or not. */ struct ScheduleData { uint256 totalAmount; address target; uint32 start; uint32 duration; bool revocable; } /** * @notice Vesting schedules of an account. * @param totalAmount the number of tokens to be vested during the vesting duration. * @param released the amount of the token released. It means that the account has called withdraw() and received * @param start the timestamp in minutes at which vesting starts. Must not be equal to zero, as it is used to * check for the existence of a vesting schedule. * @param duration duration in minutes of the period in which the tokens will vest. * `released amount` of tokens to his address. * @param revocable whether the vesting is revocable or not. */ struct VestingSchedule { uint256 totalAmount; uint256 released; uint32 created; uint32 start; uint32 duration; bool revocable; } /// @notice get keccak-256 hash of GATEKEEPER role function GATEKEEPER() external view returns (bytes32); /// @notice get keccak-256 hash of TOKEN_PROVIDER role function TOKEN_PROVIDER() external view returns (bytes32); /** * @notice get vesting schedule of an account. */ function schedules(address) external view returns ( uint256 totalAmount, uint256 released, uint32 created, uint32 start, uint32 duration, bool revocable ); /** * @notice Gets the amount of MNT that was transferred to Vesting contract * and can be transferred to other accounts via vesting process. * Transferring rewards from Vesting via withdraw method will decrease this amount. */ function allocation() external view returns (uint256); /** * @notice Gets the amount of allocated MNT tokens that are not used in any vesting schedule yet. * Creation of new vesting schedules will decrease this amount. */ function freeAllocation() external view returns (uint256); /** * @notice get Whether or not the account is in the delay list */ function delayList(address) external view returns (bool); /** * @notice Withdraw the specified number of tokens. For a successful transaction, the requirement * `amount_ > 0 && amount_ <= unreleased` must be met. * If `amount_ == MaxUint256` withdraw all unreleased tokens. * @param amount_ The number of tokens to withdraw. */ function withdraw(uint256 amount_) external; /** * @notice Increases vesting schedule allocation and transfers MNT into Vesting. * @dev RESTRICTION: TOKEN_PROVIDER only */ function refill(uint256 amount) external; /** * @notice Transfers MNT that were added to the contract without calling the refill and are unallocated. * @dev RESTRICTION: Admin only */ function sweep(address recipient, uint256 amount) external; /** * @notice Allows the admin to create a new vesting schedules. * @param schedulesData an array of vesting schedules that will be created. * @dev RESTRICTION: Admin only. */ function createVestingScheduleBatch(ScheduleData[] memory schedulesData) external; /** * @notice Allows the admin to revoke the vesting schedule. Tokens already vested * transfer to the account, the rest are returned to the vesting contract. * Accounts that are in delay list have their withdraw blocked so they would not receive anything. * @param target_ the address from which the vesting schedule is revoked. * @dev RESTRICTION: Gatekeeper only. */ function revokeVestingSchedule(address target_) external; /** * @notice Calculates the end of the vesting. * @param who_ account address for which the parameter is returned. * @return the end of the vesting. */ function endOfVesting(address who_) external view returns (uint256); /** * @notice Calculates locked amount for a given `time`. * @param who_ account address for which the parameter is returned. * @return locked amount for a given `time`. */ function lockedAmount(address who_) external view returns (uint256); /** * @notice Calculates the amount that has already vested. * @param who_ account address for which the parameter is returned. * @return the amount that has already vested. */ function vestedAmount(address who_) external view returns (uint256); /** * @notice Calculates the amount that has already vested but hasn't been released yet. * @param who_ account address for which the parameter is returned. * @return the amount that has already vested but hasn't been released yet. */ function releasableAmount(address who_) external view returns (uint256); /** * @notice Gets the amount that has already vested but hasn't been released yet if account * schedule had no starting delay (cliff). */ function getReleasableWithoutCliff(address account) external view returns (uint256); /** * @notice Add an account with revocable schedule to the delay list * @param who_ The account that is being added to the delay list * @dev RESTRICTION: Gatekeeper only. */ function addToDelayList(address who_) external; /** * @notice Remove an account from the delay list * @param who_ The account that is being removed from the delay list * @dev RESTRICTION: Gatekeeper only. */ function removeFromDelayList(address who_) external; }
contracts/interfaces/IWeightAggregator.sol
// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.17; interface IWeightAggregator { /** * @notice Returns MNTs of the account that are used in buyback weight calculation. */ function getAccountFunds(address account) external view returns (uint256); /** * @notice Returns loyalty factor of the specified account. */ function getLoyaltyFactor(address account) external view returns (uint256); /** * @notice Returns Buyback weight for the user */ function getBuybackWeight(address account) external view returns (uint256); /** * @notice Return voting weight for the user */ function getVotingWeight(address account) external view returns (uint256); }
Compiler Settings
{"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":200,"enabled":true},"metadata":{"useLiteralContent":true},"libraries":{}}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"buyback_","internalType":"contract IBuyback"},{"type":"address","name":"vesting_","internalType":"contract IVesting"},{"type":"address","name":"rewardsHub_","internalType":"contract IRewardsHub"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IBuyback"}],"name":"buyback","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getAccountFunds","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getBuybackWeight","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getLoyaltyFactor","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getVotingWeight","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IRewardsHub"}],"name":"rewardsHub","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IVesting"}],"name":"vesting","inputs":[]}]
Contract Creation Code
0x60e060405234801561001057600080fd5b50604051610a96380380610a9683398101604081905261002f91610064565b6001600160a01b0392831660805290821660a0521660c0526100b1565b6001600160a01b038116811461006157600080fd5b50565b60008060006060848603121561007957600080fd5b83516100848161004c565b60208501519093506100958161004c565b60408501519092506100a68161004c565b809150509250925092565b60805160a05160c05161096b61012b6000396000818160ec01528181610190015261053501526000818160870152818161021c01526105bf01526000818161014c015281816102a60152818161032f015281816103f5015281816104a5015281816106490152818161071c01526107cc015261096b6000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c8063956dce9c1161005b578063956dce9c1461010e578063d5da24b914610121578063f47a2e9914610134578063f8ec69111461014757600080fd5b806344c63eec14610082578063538d486d146100c65780636e8c4c54146100e7575b600080fd5b6100a97f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6100d96100d4366004610868565b61016e565b6040519081526020016100bd565b6100a97f000000000000000000000000000000000000000000000000000000000000000081565b6100d961011c366004610868565b61032b565b6100d961012f366004610868565b6103d3565b6100d9610142366004610868565b6106fa565b6100a97f000000000000000000000000000000000000000000000000000000000000000081565b6040516325d998bb60e01b81526001600160a01b0382811660048301526000917f0000000000000000000000000000000000000000000000000000000000000000909116906325d998bb90602401602060405180830381865afa1580156101d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101fd9190610898565b6040516302e4d97960e31b81526001600160a01b0384811660048301527f00000000000000000000000000000000000000000000000000000000000000001690631726cbc890602401602060405180830381865afa158015610263573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102879190610898565b6040516326d352ab60e11b81526001600160a01b0385811660048301527f00000000000000000000000000000000000000000000000000000000000000001690634da6a55690602401602060405180830381865afa1580156102ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103119190610898565b61031b91906108c7565b61032591906108c7565b92915050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663044c908b836103668561016e565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa1580156103af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103259190610898565b604051631e995dd160e31b81526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063f4caee8890602401602060405180830381865afa15801561043e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046291906108da565b61046e57506000919050565b60006104798361016e565b60405163044c908b60e01b81526001600160a01b038581166004830152602482018390529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063044c908b90604401602060405180830381865afa1580156104ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105109190610898565b604051632587701560e11b81526001600160a01b0386811660048301529192506000917f00000000000000000000000000000000000000000000000000000000000000001690634b0ee02a90602401602060405180830381865afa15801561057c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a09190610898565b6040516368929b1d60e01b81526001600160a01b0387811660048301527f000000000000000000000000000000000000000000000000000000000000000016906368929b1d90602401602060405180830381865afa158015610606573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061062a9190610898565b6040516326d352ab60e11b81526001600160a01b0388811660048301527f00000000000000000000000000000000000000000000000000000000000000001690634da6a55690602401602060405180830381865afa158015610690573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106b49190610898565b6106be91906108c7565b6106c891906108c7565b9050670de0b6b3a76400006106dd83836108fc565b6106e79190610913565b6106f190826108c7565b95945050505050565b604051631e995dd160e31b81526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063f4caee8890602401602060405180830381865afa158015610765573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061078991906108da565b61079557506000919050565b60006107a08361016e565b60405163044c908b60e01b81526001600160a01b038581166004830152602482018390529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063044c908b90604401602060405180830381865afa158015610813573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108379190610898565b9050670de0b6b3a764000061084c82846108fc565b6108569190610913565b61086090836108c7565b949350505050565b60006020828403121561087a57600080fd5b81356001600160a01b038116811461089157600080fd5b9392505050565b6000602082840312156108aa57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610325576103256108b1565b6000602082840312156108ec57600080fd5b8151801515811461089157600080fd5b8082028115828204841417610325576103256108b1565b60008261093057634e487b7160e01b600052601260045260246000fd5b50049056fea264697066735822122003db1bd54dcff127f997364b4970e23d2f7f2bb7c7e98be0149db22797d621e864736f6c634300081100330000000000000000000000002597ba2385be4d2e49aad864c377378736b680d1000000000000000000000000a59512c9471912f99958b867f6954f5bef0cb3f4000000000000000000000000fdc8c1c2352a813d902a596e8597f7215dd15087
Deployed ByteCode
0x608060405234801561001057600080fd5b506004361061007d5760003560e01c8063956dce9c1161005b578063956dce9c1461010e578063d5da24b914610121578063f47a2e9914610134578063f8ec69111461014757600080fd5b806344c63eec14610082578063538d486d146100c65780636e8c4c54146100e7575b600080fd5b6100a97f000000000000000000000000a59512c9471912f99958b867f6954f5bef0cb3f481565b6040516001600160a01b0390911681526020015b60405180910390f35b6100d96100d4366004610868565b61016e565b6040519081526020016100bd565b6100a97f000000000000000000000000fdc8c1c2352a813d902a596e8597f7215dd1508781565b6100d961011c366004610868565b61032b565b6100d961012f366004610868565b6103d3565b6100d9610142366004610868565b6106fa565b6100a97f0000000000000000000000002597ba2385be4d2e49aad864c377378736b680d181565b6040516325d998bb60e01b81526001600160a01b0382811660048301526000917f000000000000000000000000fdc8c1c2352a813d902a596e8597f7215dd15087909116906325d998bb90602401602060405180830381865afa1580156101d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101fd9190610898565b6040516302e4d97960e31b81526001600160a01b0384811660048301527f000000000000000000000000a59512c9471912f99958b867f6954f5bef0cb3f41690631726cbc890602401602060405180830381865afa158015610263573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102879190610898565b6040516326d352ab60e11b81526001600160a01b0385811660048301527f0000000000000000000000002597ba2385be4d2e49aad864c377378736b680d11690634da6a55690602401602060405180830381865afa1580156102ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103119190610898565b61031b91906108c7565b61032591906108c7565b92915050565b60007f0000000000000000000000002597ba2385be4d2e49aad864c377378736b680d16001600160a01b031663044c908b836103668561016e565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa1580156103af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103259190610898565b604051631e995dd160e31b81526001600160a01b0382811660048301526000917f0000000000000000000000002597ba2385be4d2e49aad864c377378736b680d19091169063f4caee8890602401602060405180830381865afa15801561043e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046291906108da565b61046e57506000919050565b60006104798361016e565b60405163044c908b60e01b81526001600160a01b038581166004830152602482018390529192506000917f0000000000000000000000002597ba2385be4d2e49aad864c377378736b680d1169063044c908b90604401602060405180830381865afa1580156104ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105109190610898565b604051632587701560e11b81526001600160a01b0386811660048301529192506000917f000000000000000000000000fdc8c1c2352a813d902a596e8597f7215dd150871690634b0ee02a90602401602060405180830381865afa15801561057c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a09190610898565b6040516368929b1d60e01b81526001600160a01b0387811660048301527f000000000000000000000000a59512c9471912f99958b867f6954f5bef0cb3f416906368929b1d90602401602060405180830381865afa158015610606573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061062a9190610898565b6040516326d352ab60e11b81526001600160a01b0388811660048301527f0000000000000000000000002597ba2385be4d2e49aad864c377378736b680d11690634da6a55690602401602060405180830381865afa158015610690573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106b49190610898565b6106be91906108c7565b6106c891906108c7565b9050670de0b6b3a76400006106dd83836108fc565b6106e79190610913565b6106f190826108c7565b95945050505050565b604051631e995dd160e31b81526001600160a01b0382811660048301526000917f0000000000000000000000002597ba2385be4d2e49aad864c377378736b680d19091169063f4caee8890602401602060405180830381865afa158015610765573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061078991906108da565b61079557506000919050565b60006107a08361016e565b60405163044c908b60e01b81526001600160a01b038581166004830152602482018390529192506000917f0000000000000000000000002597ba2385be4d2e49aad864c377378736b680d1169063044c908b90604401602060405180830381865afa158015610813573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108379190610898565b9050670de0b6b3a764000061084c82846108fc565b6108569190610913565b61086090836108c7565b949350505050565b60006020828403121561087a57600080fd5b81356001600160a01b038116811461089157600080fd5b9392505050565b6000602082840312156108aa57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610325576103256108b1565b6000602082840312156108ec57600080fd5b8151801515811461089157600080fd5b8082028115828204841417610325576103256108b1565b60008261093057634e487b7160e01b600052601260045260246000fd5b50049056fea264697066735822122003db1bd54dcff127f997364b4970e23d2f7f2bb7c7e98be0149db22797d621e864736f6c63430008110033