More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Collect And Vali... | 22817709 | 1147 days ago | IN | 0 POL | 0.00465098 |
Loading...
Loading
Contract Name:
InterestValidator
Compiler Version
v0.8.2+commit.661d1103
Contract Source Code (Solidity)
/** *Submitted for verification at polygonscan.com on 2021-06-24 */ pragma solidity 0.8.2; struct BassetPersonal { // Address of the bAsset address addr; // Address of the bAsset address integrator; // An ERC20 can charge transfer fee, for example USDT, DGX tokens. bool hasTxFee; // takes a byte in storage // Status of the bAsset BassetStatus status; } struct BassetData { // 1 Basset * ratio / ratioScale == x Masset (relative value) // If ratio == 10e8 then 1 bAsset = 10 mAssets // A ratio is divised as 10^(18-tokenDecimals) * measurementMultiple(relative value of 1 base unit) uint128 ratio; // Amount of the Basset that is held in Collateral uint128 vaultBalance; } // Status of the Basset - has it broken its peg? enum BassetStatus { Default, Normal, BrokenBelowPeg, BrokenAbovePeg, Blacklisted, Liquidating, Liquidated, Failed } struct BasketState { bool undergoingRecol; bool failed; } struct FeederConfig { uint256 supply; uint256 a; WeightLimits limits; } struct InvariantConfig { uint256 supply; uint256 a; WeightLimits limits; uint256 recolFee; } struct BasicConfig { uint256 a; WeightLimits limits; } struct WeightLimits { uint128 min; uint128 max; } struct AmpData { uint64 initialA; uint64 targetA; uint64 rampStartTime; uint64 rampEndTime; } struct FeederData { uint256 swapFee; uint256 redemptionFee; uint256 govFee; uint256 pendingFees; uint256 cacheSize; BassetPersonal[] bAssetPersonal; BassetData[] bAssetData; AmpData ampData; WeightLimits weightLimits; } struct MassetData { uint256 swapFee; uint256 redemptionFee; uint256 cacheSize; uint256 surplus; BassetPersonal[] bAssetPersonal; BassetData[] bAssetData; BasketState basket; AmpData ampData; WeightLimits weightLimits; } struct AssetData { uint8 idx; uint256 amt; BassetPersonal personal; } struct Asset { uint8 idx; address addr; bool exists; } abstract contract IFeederPool { // Mint function mint( address _input, uint256 _inputQuantity, uint256 _minOutputQuantity, address _recipient ) external virtual returns (uint256 mintOutput); function mintMulti( address[] calldata _inputs, uint256[] calldata _inputQuantities, uint256 _minOutputQuantity, address _recipient ) external virtual returns (uint256 mintOutput); function getMintOutput(address _input, uint256 _inputQuantity) external view virtual returns (uint256 mintOutput); function getMintMultiOutput(address[] calldata _inputs, uint256[] calldata _inputQuantities) external view virtual returns (uint256 mintOutput); // Swaps function swap( address _input, address _output, uint256 _inputQuantity, uint256 _minOutputQuantity, address _recipient ) external virtual returns (uint256 swapOutput); function getSwapOutput( address _input, address _output, uint256 _inputQuantity ) external view virtual returns (uint256 swapOutput); // Redemption function redeem( address _output, uint256 _fpTokenQuantity, uint256 _minOutputQuantity, address _recipient ) external virtual returns (uint256 outputQuantity); function redeemProportionately( uint256 _fpTokenQuantity, uint256[] calldata _minOutputQuantities, address _recipient ) external virtual returns (uint256[] memory outputQuantities); function redeemExactBassets( address[] calldata _outputs, uint256[] calldata _outputQuantities, uint256 _maxMassetQuantity, address _recipient ) external virtual returns (uint256 mAssetRedeemed); function getRedeemOutput(address _output, uint256 _fpTokenQuantity) external view virtual returns (uint256 bAssetOutput); function getRedeemExactBassetsOutput( address[] calldata _outputs, uint256[] calldata _outputQuantities ) external view virtual returns (uint256 mAssetAmount); // Views function mAsset() external view virtual returns (address); function getPrice() public view virtual returns (uint256 price, uint256 k); function getConfig() external view virtual returns (FeederConfig memory config); function getBasset(address _token) external view virtual returns (BassetPersonal memory personal, BassetData memory data); function getBassets() external view virtual returns (BassetPersonal[] memory personal, BassetData[] memory data); // SavingsManager function collectPlatformInterest() external virtual returns (uint256 mintAmount, uint256 newSupply); function collectPendingFees() external virtual; } contract ModuleKeys { // Governance // =========== // keccak256("Governance"); bytes32 internal constant KEY_GOVERNANCE = 0x9409903de1e6fd852dfc61c9dacb48196c48535b60e25abf92acc92dd689078d; //keccak256("Staking"); bytes32 internal constant KEY_STAKING = 0x1df41cd916959d1163dc8f0671a666ea8a3e434c13e40faef527133b5d167034; //keccak256("ProxyAdmin"); bytes32 internal constant KEY_PROXY_ADMIN = 0x96ed0203eb7e975a4cbcaa23951943fa35c5d8288117d50c12b3d48b0fab48d1; // mStable // ======= // keccak256("OracleHub"); bytes32 internal constant KEY_ORACLE_HUB = 0x8ae3a082c61a7379e2280f3356a5131507d9829d222d853bfa7c9fe1200dd040; // keccak256("Manager"); bytes32 internal constant KEY_MANAGER = 0x6d439300980e333f0256d64be2c9f67e86f4493ce25f82498d6db7f4be3d9e6f; //keccak256("Recollateraliser"); bytes32 internal constant KEY_RECOLLATERALISER = 0x39e3ed1fc335ce346a8cbe3e64dd525cf22b37f1e2104a755e761c3c1eb4734f; //keccak256("MetaToken"); bytes32 internal constant KEY_META_TOKEN = 0xea7469b14936af748ee93c53b2fe510b9928edbdccac3963321efca7eb1a57a2; // keccak256("SavingsManager"); bytes32 internal constant KEY_SAVINGS_MANAGER = 0x12fe936c77a1e196473c4314f3bed8eeac1d757b319abb85bdda70df35511bf1; // keccak256("Liquidator"); bytes32 internal constant KEY_LIQUIDATOR = 0x1e9cb14d7560734a61fa5ff9273953e971ff3cd9283c03d8346e3264617933d4; // keccak256("InterestValidator"); bytes32 internal constant KEY_INTEREST_VALIDATOR = 0xc10a28f028c7f7282a03c90608e38a4a646e136e614e4b07d119280c5f7f839f; } interface INexus { function governor() external view returns (address); function getModule(bytes32 key) external view returns (address); function proposeModule(bytes32 _key, address _addr) external; function cancelProposedModule(bytes32 _key) external; function acceptProposedModule(bytes32 _key) external; function acceptProposedModules(bytes32[] calldata _keys) external; function requestLockModule(bytes32 _key) external; function cancelLockModule(bytes32 _key) external; function lockModule(bytes32 _key) external; } abstract contract ImmutableModule is ModuleKeys { INexus public immutable nexus; /** * @dev Initialization function for upgradable proxy contracts * @param _nexus Nexus contract address */ constructor(address _nexus) { require(_nexus != address(0), "Nexus address is zero"); nexus = INexus(_nexus); } /** * @dev Modifier to allow function calls only from the Governor. */ modifier onlyGovernor() { _onlyGovernor(); _; } function _onlyGovernor() internal view { require(msg.sender == _governor(), "Only governor can execute"); } /** * @dev Modifier to allow function calls only from the Governance. * Governance is either Governor address or Governance address. */ modifier onlyGovernance() { require( msg.sender == _governor() || msg.sender == _governance(), "Only governance can execute" ); _; } /** * @dev Returns Governor address from the Nexus * @return Address of Governor Contract */ function _governor() internal view returns (address) { return nexus.governor(); } /** * @dev Returns Governance Module address from the Nexus * @return Address of the Governance (Phase 2) */ function _governance() internal view returns (address) { return nexus.getModule(KEY_GOVERNANCE); } /** * @dev Return SavingsManager Module address from the Nexus * @return Address of the SavingsManager Module contract */ function _savingsManager() internal view returns (address) { return nexus.getModule(KEY_SAVINGS_MANAGER); } /** * @dev Return Recollateraliser Module address from the Nexus * @return Address of the Recollateraliser Module contract (Phase 2) */ function _recollateraliser() internal view returns (address) { return nexus.getModule(KEY_RECOLLATERALISER); } /** * @dev Return Recollateraliser Module address from the Nexus * @return Address of the Recollateraliser Module contract (Phase 2) */ function _liquidator() internal view returns (address) { return nexus.getModule(KEY_LIQUIDATOR); } /** * @dev Return ProxyAdmin Module address from the Nexus * @return Address of the ProxyAdmin Module contract */ function _proxyAdmin() internal view returns (address) { return nexus.getModule(KEY_PROXY_ADMIN); } } abstract contract PausableModule is ImmutableModule { /** * @dev Emitted when the pause is triggered by Governor */ event Paused(address account); /** * @dev Emitted when the pause is lifted by Governor */ event Unpaused(address account); bool internal _paused = false; /** * @dev Modifier to make a function callable only when the contract is not paused. */ modifier whenNotPaused() { require(!_paused, "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. */ modifier whenPaused() { require(_paused, "Pausable: not paused"); _; } /** * @dev Initializes the contract in unpaused state. * Hooks into the Module to give the Governor ability to pause * @param _nexus Nexus contract address */ constructor(address _nexus) ImmutableModule(_nexus) { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. * @return Returns `true` when paused, otherwise `false` */ function paused() external view returns (bool) { return _paused; } /** * @dev Called by the Governor to pause, triggers stopped state. */ function pause() external onlyGovernor whenNotPaused { _paused = true; emit Paused(msg.sender); } /** * @dev Called by Governor to unpause, returns to normal state. */ function unpause() external onlyGovernor whenPaused { _paused = false; emit Unpaused(msg.sender); } } interface IERC20 { /** * @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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `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. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @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 Interface of the ERC20 standard as defined in the EIP. */ /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } library SafeERC20 { using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } library YieldValidator { uint256 private constant SECONDS_IN_YEAR = 365 days; uint256 private constant THIRTY_MINUTES = 30 minutes; uint256 private constant MAX_APY = 15e18; uint256 private constant TEN_BPS = 1e15; /** * @dev Validates that an interest collection does not exceed a maximum APY. If last collection * was under 30 mins ago, simply check it does not exceed 10bps * @param _newSupply New total supply of the mAsset * @param _interest Increase in total supply since last collection * @param _timeSinceLastCollection Seconds since last collection */ function validateCollection( uint256 _newSupply, uint256 _interest, uint256 _timeSinceLastCollection ) internal pure returns (uint256 extrapolatedAPY) { return validateCollection(_newSupply, _interest, _timeSinceLastCollection, MAX_APY, TEN_BPS); } /** * @dev Validates that an interest collection does not exceed a maximum APY. If last collection * was under 30 mins ago, simply check it does not exceed 10bps * @param _newSupply New total supply of the mAsset * @param _interest Increase in total supply since last collection * @param _timeSinceLastCollection Seconds since last collection * @param _maxApy Max APY where 100% == 1e18 * @param _baseApy If less than 30 mins, do not exceed this % increase */ function validateCollection( uint256 _newSupply, uint256 _interest, uint256 _timeSinceLastCollection, uint256 _maxApy, uint256 _baseApy ) internal pure returns (uint256 extrapolatedAPY) { uint256 protectedTime = _timeSinceLastCollection == 0 ? 1 : _timeSinceLastCollection; // Percentage increase in total supply // e.g. (1e20 * 1e18) / 1e24 = 1e14 (or a 0.01% increase) // e.g. (5e18 * 1e18) / 1.2e24 = 4.1667e12 // e.g. (1e19 * 1e18) / 1e21 = 1e16 uint256 oldSupply = _newSupply - _interest; uint256 percentageIncrease = (_interest * 1e18) / oldSupply; // If over 30 mins, extrapolate APY // e.g. day: (86400 * 1e18) / 3.154e7 = 2.74..e15 // e.g. 30 mins: (1800 * 1e18) / 3.154e7 = 5.7..e13 // e.g. epoch: (1593596907 * 1e18) / 3.154e7 = 50.4..e18 uint256 yearsSinceLastCollection = (protectedTime * 1e18) / SECONDS_IN_YEAR; // e.g. 0.01% (1e14 * 1e18) / 2.74..e15 = 3.65e16 or 3.65% apr // e.g. (4.1667e12 * 1e18) / 5.7..e13 = 7.1e16 or 7.1% apr // e.g. (1e16 * 1e18) / 50e18 = 2e14 extrapolatedAPY = (percentageIncrease * 1e18) / yearsSinceLastCollection; if (protectedTime > THIRTY_MINUTES) { require(extrapolatedAPY < _maxApy, "Interest protected from inflating past maxAPY"); } else { require(percentageIncrease < _baseApy, "Interest protected from inflating past 10 Bps"); } } } // SPDX-License-Identifier: AGPL-3.0-or-later /** * @title InterestValidator * @author mStable * @notice Simply validates the platform interest collection from the Feeder Pools. Normally this function * is supported by the SavingsManager, which then distributes the inflated tokens to SAVE contracts. * However, given that fPools collect value internally, we simply want to provide protections here * without actually inflating supply. As such, this code is forked from `savings/SavingsManager.sol`. * @dev VERSION: 1.0 * DATE: 2021-03-01 */ contract InterestValidator is PausableModule { event InterestCollected( address indexed feederPool, uint256 interest, uint256 newTotalSupply, uint256 apy ); event GovFeeCollected(address indexed feederPool, address mAsset, uint256 amount); mapping(address => uint256) public lastBatchCollected; constructor(address _nexus) PausableModule(_nexus) {} /** * @notice Collects and validates the interest of n feeder pools. * @dev First calls to calculate the interest that has accrued, and then validates the potential inflation * with respect to the previous timestamp. * @param _fPools Addresses of the feeder pools on which to accrue interest */ function collectAndValidateInterest(address[] calldata _fPools) external whenNotPaused { uint256 currentTime = block.timestamp; uint256 len = _fPools.length; for (uint256 i = 0; i < len; i++) { address feeder = _fPools[i]; uint256 previousBatch = lastBatchCollected[feeder]; uint256 timeSincePreviousBatch = currentTime - previousBatch; require(timeSincePreviousBatch > 12 hours, "Cannot collect twice in 12 hours"); lastBatchCollected[feeder] = currentTime; // Batch collect (uint256 interestCollected, uint256 totalSupply) = IFeederPool(feeder).collectPlatformInterest(); if (interestCollected > 0) { // Validate APY uint256 apy = YieldValidator.validateCollection( totalSupply, interestCollected, timeSincePreviousBatch ); emit InterestCollected(feeder, interestCollected, totalSupply, apy); } else { emit InterestCollected(feeder, interestCollected, totalSupply, 0); } } } /** * @dev Collects gov fees from fPools in the form of fPtoken, then converts to * mAsset and sends directly to the SavingsManager, where it will be picked up and * converted to mBPT upon the next collection */ function collectGovFees(address[] calldata _fPools) external onlyGovernor { uint256 len = _fPools.length; address savingsManager = _savingsManager(); for (uint256 i = 0; i < len; i++) { address fPool = _fPools[i]; // 1. Collect pending fees IFeederPool(fPool).collectPendingFees(); uint256 fpTokenBal = IERC20(fPool).balanceOf(address(this)); // 2. If fpTokenBal > 0, convert to mAsset and transfer to savingsManager if (fpTokenBal > 0) { address mAsset = IFeederPool(fPool).mAsset(); uint256 outputAmt = IFeederPool(fPool).redeem( mAsset, fpTokenBal, (fpTokenBal * 7) / 10, savingsManager ); emit GovFeeCollected(fPool, mAsset, outputAmt); } } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_nexus","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"feederPool","type":"address"},{"indexed":false,"internalType":"address","name":"mAsset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"GovFeeCollected","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"feederPool","type":"address"},{"indexed":false,"internalType":"uint256","name":"interest","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newTotalSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"apy","type":"uint256"}],"name":"InterestCollected","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"address[]","name":"_fPools","type":"address[]"}],"name":"collectAndValidateInterest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_fPools","type":"address[]"}],"name":"collectGovFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastBatchCollected","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nexus","outputs":[{"internalType":"contract INexus","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a06040526000805460ff1916905534801561001a57600080fd5b50604051610d6a380380610d6a833981016040819052610039916100b6565b80806001600160a01b0381166100955760405162461bcd60e51b815260206004820152601560248201527f4e657875732061646472657373206973207a65726f0000000000000000000000604482015260640160405180910390fd5b60601b6001600160601b03191660805250506000805460ff191690556100e4565b6000602082840312156100c7578081fd5b81516001600160a01b03811681146100dd578182fd5b9392505050565b60805160601c610c5b61010f6000396000818160f50152818161082801526108d90152610c5b6000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80635c975abb1161005b5780635c975abb146100d25780638456cb59146100e8578063a3f5c1d2146100f0578063a600f0dd1461012f5761007d565b80631cf743271461008257806333bda1f7146100975780633f4ba83a146100ca575b600080fd5b610095610090366004610adc565b610142565b005b6100b76100a5366004610a9d565b60016020526000908152604090205481565b6040519081526020015b60405180910390f35b610095610406565b60005460ff1660405190151581526020016100c1565b61009561049c565b6101177f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100c1565b61009561013d366004610adc565b610527565b61014a610786565b8060006101556107f0565b905060005b828110156103ff57600085858381811061018457634e487b7160e01b600052603260045260246000fd5b90506020020160208101906101999190610a9d565b9050806001600160a01b03166398fec3af6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156101d657600080fd5b505af11580156101ea573d6000803e3d6000fd5b50506040516370a0823160e01b8152306004820152600092506001600160a01b03841691506370a082319060240160206040518083038186803b15801561023057600080fd5b505afa158015610244573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102689190610b4b565b905080156103ea576000826001600160a01b031663178d341f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156102ab57600080fd5b505afa1580156102bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102e39190610ac0565b905060006001600160a01b0384166343bcfab68385600a610305826007610ba6565b61030f9190610b86565b6040516001600160e01b031960e086901b1681526001600160a01b039384166004820152602481019290925260448201529089166064820152608401602060405180830381600087803b15801561036557600080fd5b505af1158015610379573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061039d9190610b4b565b604080516001600160a01b03858116825260208201849052929350918616917f24b98558c8051808230c888e96f8352b78e39de78fc2300c4e922c9b48e9d176910160405180910390a250505b505080806103f790610bdc565b91505061015a565b5050505050565b61040e610786565b60005460ff1661045c5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064015b60405180910390fd5b6000805460ff191690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b6104a4610786565b60005460ff16156104ea5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610453565b6000805460ff191660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610492565b60005460ff161561056d5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610453565b428160005b818110156103ff57600085858381811061059c57634e487b7160e01b600052603260045260246000fd5b90506020020160208101906105b19190610a9d565b6001600160a01b0381166000908152600160205260408120549192506105d78287610bc5565b905061a8c0811161062a5760405162461bcd60e51b815260206004820181905260248201527f43616e6e6f7420636f6c6c65637420747769636520696e20313220686f7572736044820152606401610453565b6001600160a01b0383166000818152600160205260408082208990558051633f4480f560e11b81528151929384939092637e8901ea926004808201939182900301818787803b15801561067c57600080fd5b505af1158015610690573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106b49190610b63565b909250905081156107215760006106cc8284866108af565b60408051858152602081018590529081018290529091506001600160a01b038716907f0abcfa9ece819bcdcfa052a818ce11f0b9fad8b3e3ccd98f120c40be689b690f9060600160405180910390a25061076e565b604080518381526020810183905260008183015290516001600160a01b038716917f0abcfa9ece819bcdcfa052a818ce11f0b9fad8b3e3ccd98f120c40be689b690f919081900360600190a25b5050505050808061077e90610bdc565b915050610572565b61078e6108d5565b6001600160a01b0316336001600160a01b0316146107ee5760405162461bcd60e51b815260206004820152601960248201527f4f6e6c7920676f7665726e6f722063616e2065786563757465000000000000006044820152606401610453565b565b6040516385acd64160e01b81527f12fe936c77a1e196473c4314f3bed8eeac1d757b319abb85bdda70df35511bf160048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906385acd6419060240160206040518083038186803b15801561087257600080fd5b505afa158015610886573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108aa9190610ac0565b905090565b60006108cd84848467d02ab486cedc000066038d7ea4c68000610930565b949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b15801561087257600080fd5b600080841561093f5784610942565b60015b905060006109508789610bc5565b905060008161096789670de0b6b3a7640000610ba6565b6109719190610b86565b905060006301e1338061098c85670de0b6b3a7640000610ba6565b6109969190610b86565b9050806109ab83670de0b6b3a7640000610ba6565b6109b59190610b86565b9450610708841115610a2b57868510610a265760405162461bcd60e51b815260206004820152602d60248201527f496e7465726573742070726f7465637465642066726f6d20696e666c6174696e60448201526c672070617374206d617841505960981b6064820152608401610453565b610a90565b858210610a905760405162461bcd60e51b815260206004820152602d60248201527f496e7465726573742070726f7465637465642066726f6d20696e666c6174696e60448201526c6720706173742031302042707360981b6064820152608401610453565b5050505095945050505050565b600060208284031215610aae578081fd5b8135610ab981610c0d565b9392505050565b600060208284031215610ad1578081fd5b8151610ab981610c0d565b60008060208385031215610aee578081fd5b823567ffffffffffffffff80821115610b05578283fd5b818501915085601f830112610b18578283fd5b813581811115610b26578384fd5b8660208083028501011115610b39578384fd5b60209290920196919550909350505050565b600060208284031215610b5c578081fd5b5051919050565b60008060408385031215610b75578182fd5b505080516020909101519092909150565b600082610ba157634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615610bc057610bc0610bf7565b500290565b600082821015610bd757610bd7610bf7565b500390565b6000600019821415610bf057610bf0610bf7565b5060010190565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b0381168114610c2257600080fd5b5056fea26469706673582212200d751e4ce4578f3e57652e8c5043bf35a96e109a44d9efd3ec0bd5bbb8b7d50264736f6c634300080200330000000000000000000000003c6fbb8cbfcb75ecec5128e9f73307f2cb33f2f6
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061007d5760003560e01c80635c975abb1161005b5780635c975abb146100d25780638456cb59146100e8578063a3f5c1d2146100f0578063a600f0dd1461012f5761007d565b80631cf743271461008257806333bda1f7146100975780633f4ba83a146100ca575b600080fd5b610095610090366004610adc565b610142565b005b6100b76100a5366004610a9d565b60016020526000908152604090205481565b6040519081526020015b60405180910390f35b610095610406565b60005460ff1660405190151581526020016100c1565b61009561049c565b6101177f0000000000000000000000003c6fbb8cbfcb75ecec5128e9f73307f2cb33f2f681565b6040516001600160a01b0390911681526020016100c1565b61009561013d366004610adc565b610527565b61014a610786565b8060006101556107f0565b905060005b828110156103ff57600085858381811061018457634e487b7160e01b600052603260045260246000fd5b90506020020160208101906101999190610a9d565b9050806001600160a01b03166398fec3af6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156101d657600080fd5b505af11580156101ea573d6000803e3d6000fd5b50506040516370a0823160e01b8152306004820152600092506001600160a01b03841691506370a082319060240160206040518083038186803b15801561023057600080fd5b505afa158015610244573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102689190610b4b565b905080156103ea576000826001600160a01b031663178d341f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156102ab57600080fd5b505afa1580156102bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102e39190610ac0565b905060006001600160a01b0384166343bcfab68385600a610305826007610ba6565b61030f9190610b86565b6040516001600160e01b031960e086901b1681526001600160a01b039384166004820152602481019290925260448201529089166064820152608401602060405180830381600087803b15801561036557600080fd5b505af1158015610379573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061039d9190610b4b565b604080516001600160a01b03858116825260208201849052929350918616917f24b98558c8051808230c888e96f8352b78e39de78fc2300c4e922c9b48e9d176910160405180910390a250505b505080806103f790610bdc565b91505061015a565b5050505050565b61040e610786565b60005460ff1661045c5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064015b60405180910390fd5b6000805460ff191690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b6104a4610786565b60005460ff16156104ea5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610453565b6000805460ff191660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610492565b60005460ff161561056d5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610453565b428160005b818110156103ff57600085858381811061059c57634e487b7160e01b600052603260045260246000fd5b90506020020160208101906105b19190610a9d565b6001600160a01b0381166000908152600160205260408120549192506105d78287610bc5565b905061a8c0811161062a5760405162461bcd60e51b815260206004820181905260248201527f43616e6e6f7420636f6c6c65637420747769636520696e20313220686f7572736044820152606401610453565b6001600160a01b0383166000818152600160205260408082208990558051633f4480f560e11b81528151929384939092637e8901ea926004808201939182900301818787803b15801561067c57600080fd5b505af1158015610690573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106b49190610b63565b909250905081156107215760006106cc8284866108af565b60408051858152602081018590529081018290529091506001600160a01b038716907f0abcfa9ece819bcdcfa052a818ce11f0b9fad8b3e3ccd98f120c40be689b690f9060600160405180910390a25061076e565b604080518381526020810183905260008183015290516001600160a01b038716917f0abcfa9ece819bcdcfa052a818ce11f0b9fad8b3e3ccd98f120c40be689b690f919081900360600190a25b5050505050808061077e90610bdc565b915050610572565b61078e6108d5565b6001600160a01b0316336001600160a01b0316146107ee5760405162461bcd60e51b815260206004820152601960248201527f4f6e6c7920676f7665726e6f722063616e2065786563757465000000000000006044820152606401610453565b565b6040516385acd64160e01b81527f12fe936c77a1e196473c4314f3bed8eeac1d757b319abb85bdda70df35511bf160048201526000907f0000000000000000000000003c6fbb8cbfcb75ecec5128e9f73307f2cb33f2f66001600160a01b0316906385acd6419060240160206040518083038186803b15801561087257600080fd5b505afa158015610886573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108aa9190610ac0565b905090565b60006108cd84848467d02ab486cedc000066038d7ea4c68000610930565b949350505050565b60007f0000000000000000000000003c6fbb8cbfcb75ecec5128e9f73307f2cb33f2f66001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b15801561087257600080fd5b600080841561093f5784610942565b60015b905060006109508789610bc5565b905060008161096789670de0b6b3a7640000610ba6565b6109719190610b86565b905060006301e1338061098c85670de0b6b3a7640000610ba6565b6109969190610b86565b9050806109ab83670de0b6b3a7640000610ba6565b6109b59190610b86565b9450610708841115610a2b57868510610a265760405162461bcd60e51b815260206004820152602d60248201527f496e7465726573742070726f7465637465642066726f6d20696e666c6174696e60448201526c672070617374206d617841505960981b6064820152608401610453565b610a90565b858210610a905760405162461bcd60e51b815260206004820152602d60248201527f496e7465726573742070726f7465637465642066726f6d20696e666c6174696e60448201526c6720706173742031302042707360981b6064820152608401610453565b5050505095945050505050565b600060208284031215610aae578081fd5b8135610ab981610c0d565b9392505050565b600060208284031215610ad1578081fd5b8151610ab981610c0d565b60008060208385031215610aee578081fd5b823567ffffffffffffffff80821115610b05578283fd5b818501915085601f830112610b18578283fd5b813581811115610b26578384fd5b8660208083028501011115610b39578384fd5b60209290920196919550909350505050565b600060208284031215610b5c578081fd5b5051919050565b60008060408385031215610b75578182fd5b505080516020909101519092909150565b600082610ba157634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615610bc057610bc0610bf7565b500290565b600082821015610bd757610bd7610bf7565b500390565b6000600019821415610bf057610bf0610bf7565b5060010190565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b0381168114610c2257600080fd5b5056fea26469706673582212200d751e4ce4578f3e57652e8c5043bf35a96e109a44d9efd3ec0bd5bbb8b7d50264736f6c63430008020033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000003c6fbb8cbfcb75ecec5128e9f73307f2cb33f2f6
-----Decoded View---------------
Arg [0] : _nexus (address): 0x3C6fbB8cbfCB75ecEC5128e9f73307f2cB33f2f6
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000003c6fbb8cbfcb75ecec5128e9f73307f2cb33f2f6
Deployed Bytecode Sourcemap
29410:3241:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31675:973;;;;;;:::i;:::-;;:::i;:::-;;29708:53;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;2949:25:1;;;2937:2;2922:18;29708:53:0;;;;;;;;11650:122;;;:::i;11259:80::-;11300:4;11324:7;;;11259:80;;2776:14:1;;2769:22;2751:41;;2739:2;2724:18;11259:80:0;2706:92:1;11435:120:0;;;:::i;7541:29::-;;;;;;;;-1:-1:-1;;;;;1836:32:1;;;1818:51;;1806:2;1791:18;7541:29:0;1773:102:1;30165:1261:0;;;;;;:::i;:::-;;:::i;31675:973::-;7975:15;:13;:15::i;:::-;31774:7;31760:11:::1;31826:17;:15;:17::i;:::-;31801:42;;31859:9;31854:787;31878:3;31874:1;:7;31854:787;;;31903:13;31919:7;;31927:1;31919:10;;;;;-1:-1:-1::0;;;31919:10:0::1;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;31903:26;;31996:5;-1:-1:-1::0;;;;;31984:37:0::1;;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;32059:38:0::1;::::0;-1:-1:-1;;;32059:38:0;;32091:4:::1;32059:38;::::0;::::1;1818:51:1::0;32038:18:0::1;::::0;-1:-1:-1;;;;;;32059:23:0;::::1;::::0;-1:-1:-1;32059:23:0::1;::::0;1791:18:1;;32059:38:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;32038:59:::0;-1:-1:-1;32203:14:0;;32199:431:::1;;32238:14;32267:5;-1:-1:-1::0;;;;;32255:25:0::1;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;32238:44:::0;-1:-1:-1;32301:17:0::1;-1:-1:-1::0;;;;;32342:25:0;::::1;;32238:44:::0;32427:10;32483:2:::1;32465:14;32427:10:::0;32478:1:::1;32465:14;:::i;:::-;32464:21;;;;:::i;:::-;32342:207;::::0;-1:-1:-1;;;;;;32342:207:0::1;::::0;;;;;;-1:-1:-1;;;;;2446:15:1;;;32342:207:0::1;::::0;::::1;2428:34:1::0;2478:18;;;2471:34;;;;2521:18;;;2514:34;2584:15;;;2564:18;;;2557:43;2362:19;;32342:207:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;32573:41;::::0;;-1:-1:-1;;;;;2072:32:1;;;2054:51;;2136:2;2121:18;;2114:34;;;32301:248:0;;-1:-1:-1;32573:41:0;;::::1;::::0;::::1;::::0;2027:18:1;32573:41:0::1;;;;;;;32199:431;;;31854:787;;31883:3;;;;;:::i;:::-;;;;31854:787;;;;8001:1;;31675:973:::0;;:::o;11650:122::-;7975:15;:13;:15::i;:::-;10763:7:::1;::::0;::::1;;10755:40;;;::::0;-1:-1:-1;;;10755:40:0;;3409:2:1;10755:40:0::1;::::0;::::1;3391:21:1::0;3448:2;3428:18;;;3421:30;-1:-1:-1;;;3467:18:1;;;3460:50;3527:18;;10755:40:0::1;;;;;;;;;11723:5:::2;11713:15:::0;;-1:-1:-1;;11713:15:0::2;::::0;;11744:20:::2;::::0;11753:10:::2;1818:51:1::0;;11744:20:0::2;::::0;1806:2:1;1791:18;11744:20:0::2;;;;;;;;11650:122::o:0;11435:120::-;7975:15;:13;:15::i;:::-;10564:7:::1;::::0;::::1;;10563:8;10555:37;;;::::0;-1:-1:-1;;;10555:37:0;;4887:2:1;10555:37:0::1;::::0;::::1;4869:21:1::0;4926:2;4906:18;;;4899:30;-1:-1:-1;;;4945:18:1;;;4938:46;5001:18;;10555:37:0::1;4859:166:1::0;10555:37:0::1;11499:7:::2;:14:::0;;-1:-1:-1;;11499:14:0::2;11509:4;11499:14;::::0;;11529:18:::2;::::0;11536:10:::2;1818:51:1::0;;11529:18:0::2;::::0;1806:2:1;1791:18;11529::0::2;1773:102:1::0;30165:1261:0;10564:7;;;;10563:8;10555:37;;;;-1:-1:-1;;;10555:37:0;;4887:2:1;10555:37:0;;;4869:21:1;4926:2;4906:18;;;4899:30;-1:-1:-1;;;4945:18:1;;;4938:46;5001:18;;10555:37:0;4859:166:1;10555:37:0;30285:15:::1;30327:7:::0;30263:19:::1;30354:1065;30378:3;30374:1;:7;30354:1065;;;30403:14;30420:7;;30428:1;30420:10;;;;;-1:-1:-1::0;;;30420:10:0::1;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;30471:26:0;::::1;30447:21;30471:26:::0;;;:18:::1;:26;::::0;;;;;30403:27;;-1:-1:-1;30545:27:0::1;30471:26:::0;30545:11;:27:::1;:::i;:::-;30512:60;;30620:8;30595:22;:33;30587:78;;;::::0;-1:-1:-1;;;30587:78:0;;4172:2:1;30587:78:0::1;::::0;::::1;4154:21:1::0;;;4191:18;;;4184:30;4250:34;4230:18;;;4223:62;4302:18;;30587:78:0::1;4144:182:1::0;30587:78:0::1;-1:-1:-1::0;;;;;30680:26:0;::::1;;::::0;;;:18:::1;:26;::::0;;;;;:40;;;30835:45;;-1:-1:-1;;;30835:45:0;;;;30680:26;;;;;;30835:43:::1;::::0;:45:::1;::::0;;::::1;::::0;;;;;;;30680:26;;30835:45;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;30767:113:::0;;-1:-1:-1;30767:113:0;-1:-1:-1;30901:21:0;;30897:511:::1;;30976:11;31011:187;31071:11;31109:17;31153:22;31011:33;:187::i;:::-;31224:62;::::0;;5836:25:1;;;5892:2;5877:18;;5870:34;;;5920:18;;;5913:34;;;30976:222:0;;-1:-1:-1;;;;;;31224:62:0;::::1;::::0;::::1;::::0;5824:2:1;5809:18;31224:62:0::1;;;;;;;30897:511;;;;31332:60;::::0;;5836:25:1;;;5892:2;5877:18;;5870:34;;;-1:-1:-1;5920:18:1;;;5913:34;31332:60:0;;-1:-1:-1;;;;;31332:60:0;::::1;::::0;::::1;::::0;;;;;5824:2:1;31332:60:0;;::::1;30897:511;30354:1065;;;;;30383:3;;;;;:::i;:::-;;;;30354:1065;;8018:121:::0;8090:11;:9;:11::i;:::-;-1:-1:-1;;;;;8076:25:0;:10;-1:-1:-1;;;;;8076:25:0;;8068:63;;;;-1:-1:-1;;;8068:63:0;;4533:2:1;8068:63:0;;;4515:21:1;4572:2;4552:18;;;4545:30;4611:27;4591:18;;;4584:55;4656:18;;8068:63:0;4505:175:1;8068:63:0;8018:121::o;9125:::-;9202:36;;-1:-1:-1;;;9202:36:0;;6495:66;9202:36;;;2949:25:1;9175:7:0;;9202:5;-1:-1:-1;;;;;9202:15:0;;;;2922:18:1;;9202:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9195:43;;9125:121;:::o;26355:307::-;26513:23;26569:85;26588:10;26600:9;26611:24;25879:5;25926:4;26569:18;:85::i;:::-;26549:105;26355:307;-1:-1:-1;;;;26355:307:0:o;8625:95::-;8669:7;8696:5;-1:-1:-1;;;;;8696:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27245:1549;27456:23;;27516:29;;:60;;27552:24;27516:60;;;27548:1;27516:60;27492:84;-1:-1:-1;27801:17:0;27821:22;27834:9;27821:10;:22;:::i;:::-;27801:42;-1:-1:-1;27854:26:0;27801:42;27884:16;:9;27896:4;27884:16;:::i;:::-;27883:30;;;;:::i;:::-;27854:59;-1:-1:-1;28162:32:0;25768:8;28198:20;:13;28214:4;28198:20;:::i;:::-;28197:40;;;;:::i;:::-;28162:75;-1:-1:-1;28162:75:0;28455:25;:18;28476:4;28455:25;:::i;:::-;28454:54;;;;:::i;:::-;28436:72;;25825:10;28525:13;:30;28521:266;;;28598:7;28580:15;:25;28572:83;;;;-1:-1:-1;;;28572:83:0;;5232:2:1;28572:83:0;;;5214:21:1;5271:2;5251:18;;;5244:30;5310:34;5290:18;;;5283:62;-1:-1:-1;;;5361:18:1;;;5354:43;5414:19;;28572:83:0;5204:235:1;28572:83:0;28521:266;;;28717:8;28696:18;:29;28688:87;;;;-1:-1:-1;;;28688:87:0;;3758:2:1;28688:87:0;;;3740:21:1;3797:2;3777:18;;;3770:30;3836:34;3816:18;;;3809:62;-1:-1:-1;;;3887:18:1;;;3880:43;3940:19;;28688:87:0;3730:235:1;28688:87:0;27245:1549;;;;;;;;;;;:::o;14:257:1:-;;126:2;114:9;105:7;101:23;97:32;94:2;;;147:6;139;132:22;94:2;191:9;178:23;210:31;235:5;210:31;:::i;:::-;260:5;84:187;-1:-1:-1;;;84:187:1:o;276:261::-;;399:2;387:9;378:7;374:23;370:32;367:2;;;420:6;412;405:22;367:2;457:9;451:16;476:31;501:5;476:31;:::i;542:666::-;;;689:2;677:9;668:7;664:23;660:32;657:2;;;710:6;702;695:22;657:2;755:9;742:23;784:18;825:2;817:6;814:14;811:2;;;846:6;838;831:22;811:2;889:6;878:9;874:22;864:32;;934:7;927:4;923:2;919:13;915:27;905:2;;961:6;953;946:22;905:2;1006;993:16;1032:2;1024:6;1021:14;1018:2;;;1053:6;1045;1038:22;1018:2;1112:7;1107:2;1101;1093:6;1089:15;1085:2;1081:24;1077:33;1074:46;1071:2;;;1138:6;1130;1123:22;1071:2;1174;1166:11;;;;;1196:6;;-1:-1:-1;647:561:1;;-1:-1:-1;;;;647:561:1:o;1213:194::-;;1336:2;1324:9;1315:7;1311:23;1307:32;1304:2;;;1357:6;1349;1342:22;1304:2;-1:-1:-1;1385:16:1;;1294:113;-1:-1:-1;1294:113:1:o;1412:255::-;;;1552:2;1540:9;1531:7;1527:23;1523:32;1520:2;;;1573:6;1565;1558:22;1520:2;-1:-1:-1;;1601:16:1;;1657:2;1642:18;;;1636:25;1601:16;;1636:25;;-1:-1:-1;1510:157:1:o;6282:217::-;;6348:1;6338:2;;-1:-1:-1;;;6373:31:1;;6427:4;6424:1;6417:15;6455:4;6380:1;6445:15;6338:2;-1:-1:-1;6484:9:1;;6328:171::o;6504:168::-;;6610:1;6606;6602:6;6598:14;6595:1;6592:21;6587:1;6580:9;6573:17;6569:45;6566:2;;;6617:18;;:::i;:::-;-1:-1:-1;6657:9:1;;6556:116::o;6677:125::-;;6745:1;6742;6739:8;6736:2;;;6750:18;;:::i;:::-;-1:-1:-1;6787:9:1;;6726:76::o;6807:135::-;;-1:-1:-1;;6867:17:1;;6864:2;;;6887:18;;:::i;:::-;-1:-1:-1;6934:1:1;6923:13;;6854:88::o;6947:127::-;7008:10;7003:3;6999:20;6996:1;6989:31;7039:4;7036:1;7029:15;7063:4;7060:1;7053:15;7079:131;-1:-1:-1;;;;;7154:31:1;;7144:42;;7134:2;;7200:1;7197;7190:12;7134:2;7124:86;:::o
Swarm Source
ipfs://0d751e4ce4578f3e57652e8c5043bf35a96e109a44d9efd3ec0bd5bbb8b7d502
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.