Polygon Sponsored slots available. Book your slot here!
Overview
POL Balance
0 POL
POL Value
$0.00Token Holdings
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 1,147 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Collect And Stre... | 57737926 | 186 days ago | IN | 0 POL | 0.01100457 | ||||
Collect And Stre... | 57699726 | 187 days ago | IN | 0 POL | 0.01100214 | ||||
Collect And Stre... | 57660993 | 188 days ago | IN | 0 POL | 0.01118547 | ||||
Collect And Stre... | 57622730 | 189 days ago | IN | 0 POL | 0.01107876 | ||||
Collect And Stre... | 57584520 | 190 days ago | IN | 0 POL | 0.01100457 | ||||
Collect And Stre... | 57546506 | 191 days ago | IN | 0 POL | 0.01100253 | ||||
Collect And Stre... | 57507438 | 192 days ago | IN | 0 POL | 0.01156071 | ||||
Collect And Stre... | 57468529 | 193 days ago | IN | 0 POL | 0.01187723 | ||||
Collect And Stre... | 57430096 | 194 days ago | IN | 0 POL | 0.01238047 | ||||
Collect And Stre... | 57392122 | 195 days ago | IN | 0 POL | 0.01100259 | ||||
Collect And Stre... | 57353314 | 196 days ago | IN | 0 POL | 0.01229794 | ||||
Collect And Stre... | 57314708 | 197 days ago | IN | 0 POL | 0.01211194 | ||||
Collect And Stre... | 57276895 | 198 days ago | IN | 0 POL | 0.01153255 | ||||
Collect And Stre... | 57239728 | 199 days ago | IN | 0 POL | 0.01227502 | ||||
Collect And Stre... | 57201897 | 200 days ago | IN | 0 POL | 0.01106655 | ||||
Collect And Stre... | 57163569 | 201 days ago | IN | 0 POL | 0.01301958 | ||||
Collect And Stre... | 57125756 | 202 days ago | IN | 0 POL | 0.0122889 | ||||
Collect And Stre... | 57088208 | 203 days ago | IN | 0 POL | 0.01080071 | ||||
Collect And Stre... | 57051116 | 204 days ago | IN | 0 POL | 0.01317038 | ||||
Collect And Stre... | 57014155 | 205 days ago | IN | 0 POL | 0.01288567 | ||||
Collect And Stre... | 56976501 | 206 days ago | IN | 0 POL | 0.01202342 | ||||
Collect And Stre... | 56938315 | 207 days ago | IN | 0 POL | 0.01193995 | ||||
Collect And Stre... | 56899227 | 208 days ago | IN | 0 POL | 0.01126566 | ||||
Collect And Stre... | 56860623 | 209 days ago | IN | 0 POL | 0.01100214 | ||||
Collect And Stre... | 56820587 | 210 days ago | IN | 0 POL | 0.011077 |
Loading...
Loading
Contract Name:
SavingsManager
Compiler Version
v0.8.2+commit.661d1103
Contract Source Code (Solidity)
/** *Submitted for verification at polygonscan.com on 2021-06-25 */ 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; } // Status of the Basset - has it broken its peg? enum BassetStatus { Default, Normal, BrokenBelowPeg, BrokenAbovePeg, Blacklisted, Liquidating, Liquidated, Failed } 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; } abstract contract IMasset { // 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 _mAssetQuantity, uint256 _minOutputQuantity, address _recipient ) external virtual returns (uint256 outputQuantity); function redeemMasset( uint256 _mAssetQuantity, 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 _mAssetQuantity) external view virtual returns (uint256 bAssetOutput); function getRedeemExactBassetsOutput( address[] calldata _outputs, uint256[] calldata _outputQuantities ) external view virtual returns (uint256 mAssetAmount); // Views function getBasket() external view virtual returns (bool, bool); 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); function bAssetIndexes(address) external view virtual returns (uint8); function getPrice() external view virtual returns (uint256 price, uint256 k); // SavingsManager function collectInterest() external virtual returns (uint256 swapFeesGained, uint256 newSupply); function collectPlatformInterest() external virtual returns (uint256 mintAmount, uint256 newSupply); // Admin function setCacheSize(uint256 _cacheSize) external virtual; function setFees(uint256 _swapFee, uint256 _redemptionFee) external virtual; function setTransferFeesFlag(address _bAsset, bool _flag) external virtual; function migrateBassets(address[] calldata _bAssets, address _newIntegration) external virtual; } interface ISavingsContractV2 { // DEPRECATED but still backwards compatible function redeem(uint256 _amount) external returns (uint256 massetReturned); function creditBalances(address) external view returns (uint256); // V1 & V2 (use balanceOf) // -------------------------------------------- function depositInterest(uint256 _amount) external; // V1 & V2 function depositSavings(uint256 _amount) external returns (uint256 creditsIssued); // V1 & V2 function depositSavings(uint256 _amount, address _beneficiary) external returns (uint256 creditsIssued); // V2 function redeemCredits(uint256 _amount) external returns (uint256 underlyingReturned); // V2 function redeemUnderlying(uint256 _amount) external returns (uint256 creditsBurned); // V2 function exchangeRate() external view returns (uint256); // V1 & V2 function balanceOfUnderlying(address _user) external view returns (uint256 balance); // V2 function underlyingToCredits(uint256 _credits) external view returns (uint256 underlying); // V2 function creditsToUnderlying(uint256 _underlying) external view returns (uint256 credits); // V2 } interface IRevenueRecipient { /** @dev Recipient */ function notifyRedistributionAmount(address _mAsset, uint256 _amount) external; function depositToPool(address[] calldata _mAssets, uint256[] calldata _percentages) external; } interface ISavingsManager { /** @dev Admin privs */ function distributeUnallocatedInterest(address _mAsset) external; /** @dev Liquidator */ function depositLiquidation(address _mAsset, uint256 _liquidation) external; /** @dev Liquidator */ function collectAndStreamInterest(address _mAsset) external; /** @dev Public privs */ function collectAndDistributeInterest(address _mAsset) external; /** @dev getter for public lastBatchCollected mapping */ function lastBatchCollected(address _mAsset) external view returns (uint256); } 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 StableMath { /** * @dev Scaling unit for use in specific calculations, * where 1 * 10**18, or 1e18 represents a unit '1' */ uint256 private constant FULL_SCALE = 1e18; /** * @dev Token Ratios are used when converting between units of bAsset, mAsset and MTA * Reasoning: Takes into account token decimals, and difference in base unit (i.e. grams to Troy oz for gold) * bAsset ratio unit for use in exact calculations, * where (1 bAsset unit * bAsset.ratio) / ratioScale == x mAsset unit */ uint256 private constant RATIO_SCALE = 1e8; /** * @dev Provides an interface to the scaling unit * @return Scaling unit (1e18 or 1 * 10**18) */ function getFullScale() internal pure returns (uint256) { return FULL_SCALE; } /** * @dev Provides an interface to the ratio unit * @return Ratio scale unit (1e8 or 1 * 10**8) */ function getRatioScale() internal pure returns (uint256) { return RATIO_SCALE; } /** * @dev Scales a given integer to the power of the full scale. * @param x Simple uint256 to scale * @return Scaled value a to an exact number */ function scaleInteger(uint256 x) internal pure returns (uint256) { return x * FULL_SCALE; } /*************************************** PRECISE ARITHMETIC ****************************************/ /** * @dev Multiplies two precise units, and then truncates by the full scale * @param x Left hand input to multiplication * @param y Right hand input to multiplication * @return Result after multiplying the two inputs and then dividing by the shared * scale unit */ function mulTruncate(uint256 x, uint256 y) internal pure returns (uint256) { return mulTruncateScale(x, y, FULL_SCALE); } /** * @dev Multiplies two precise units, and then truncates by the given scale. For example, * when calculating 90% of 10e18, (10e18 * 9e17) / 1e18 = (9e36) / 1e18 = 9e18 * @param x Left hand input to multiplication * @param y Right hand input to multiplication * @param scale Scale unit * @return Result after multiplying the two inputs and then dividing by the shared * scale unit */ function mulTruncateScale( uint256 x, uint256 y, uint256 scale ) internal pure returns (uint256) { // e.g. assume scale = fullScale // z = 10e18 * 9e17 = 9e36 // return 9e36 / 1e18 = 9e18 return (x * y) / scale; } /** * @dev Multiplies two precise units, and then truncates by the full scale, rounding up the result * @param x Left hand input to multiplication * @param y Right hand input to multiplication * @return Result after multiplying the two inputs and then dividing by the shared * scale unit, rounded up to the closest base unit. */ function mulTruncateCeil(uint256 x, uint256 y) internal pure returns (uint256) { // e.g. 8e17 * 17268172638 = 138145381104e17 uint256 scaled = x * y; // e.g. 138145381104e17 + 9.99...e17 = 138145381113.99...e17 uint256 ceil = scaled + FULL_SCALE - 1; // e.g. 13814538111.399...e18 / 1e18 = 13814538111 return ceil / FULL_SCALE; } /** * @dev Precisely divides two units, by first scaling the left hand operand. Useful * for finding percentage weightings, i.e. 8e18/10e18 = 80% (or 8e17) * @param x Left hand input to division * @param y Right hand input to division * @return Result after multiplying the left operand by the scale, and * executing the division on the right hand input. */ function divPrecisely(uint256 x, uint256 y) internal pure returns (uint256) { // e.g. 8e18 * 1e18 = 8e36 // e.g. 8e36 / 10e18 = 8e17 return (x * FULL_SCALE) / y; } /*************************************** RATIO FUNCS ****************************************/ /** * @dev Multiplies and truncates a token ratio, essentially flooring the result * i.e. How much mAsset is this bAsset worth? * @param x Left hand operand to multiplication (i.e Exact quantity) * @param ratio bAsset ratio * @return c Result after multiplying the two inputs and then dividing by the ratio scale */ function mulRatioTruncate(uint256 x, uint256 ratio) internal pure returns (uint256 c) { return mulTruncateScale(x, ratio, RATIO_SCALE); } /** * @dev Multiplies and truncates a token ratio, rounding up the result * i.e. How much mAsset is this bAsset worth? * @param x Left hand input to multiplication (i.e Exact quantity) * @param ratio bAsset ratio * @return Result after multiplying the two inputs and then dividing by the shared * ratio scale, rounded up to the closest base unit. */ function mulRatioTruncateCeil(uint256 x, uint256 ratio) internal pure returns (uint256) { // e.g. How much mAsset should I burn for this bAsset (x)? // 1e18 * 1e8 = 1e26 uint256 scaled = x * ratio; // 1e26 + 9.99e7 = 100..00.999e8 uint256 ceil = scaled + RATIO_SCALE - 1; // return 100..00.999e8 / 1e8 = 1e18 return ceil / RATIO_SCALE; } /** * @dev Precisely divides two ratioed units, by first scaling the left hand operand * i.e. How much bAsset is this mAsset worth? * @param x Left hand operand in division * @param ratio bAsset ratio * @return c Result after multiplying the left operand by the scale, and * executing the division on the right hand input. */ function divRatioPrecisely(uint256 x, uint256 ratio) internal pure returns (uint256 c) { // e.g. 1e14 * 1e8 = 1e22 // return 1e22 / 1e12 = 1e10 return (x * RATIO_SCALE) / ratio; } /*************************************** HELPERS ****************************************/ /** * @dev Calculates minimum of two numbers * @param x Left hand input * @param y Right hand input * @return Minimum of the two inputs */ function min(uint256 x, uint256 y) internal pure returns (uint256) { return x > y ? y : x; } /** * @dev Calculated maximum of two numbers * @param x Left hand input * @param y Right hand input * @return Maximum of the two inputs */ function max(uint256 x, uint256 y) internal pure returns (uint256) { return x > y ? x : y; } /** * @dev Clamps a value to an upper bound * @param x Left hand input * @param upperBound Maximum possible value to return * @return Input x clamped to a maximum value, upperBound */ function clamp(uint256 x, uint256 upperBound) internal pure returns (uint256) { return x > upperBound ? upperBound : x; } } 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 // External // Internal // Libs /** * @title SavingsManager * @author mStable * @notice Savings Manager collects interest from mAssets and sends them to the * corresponding Savings Contract, performing some validation in the process. * @dev VERSION: 1.3 * DATE: 2020-12-09 */ contract SavingsManager is ISavingsManager, PausableModule { using StableMath for uint256; using SafeERC20 for IERC20; // Core admin events event RevenueRecipientSet(address indexed mAsset, address recipient); event SavingsContractAdded(address indexed mAsset, address savingsContract); event SavingsContractUpdated(address indexed mAsset, address savingsContract); event SavingsRateChanged(uint256 newSavingsRate); event StreamsFrozen(); // Interest collection event LiquidatorDeposited(address indexed mAsset, uint256 amount); event InterestCollected( address indexed mAsset, uint256 interest, uint256 newTotalSupply, uint256 apy ); event InterestDistributed(address indexed mAsset, uint256 amountSent); event RevenueRedistributed(address indexed mAsset, address recipient, uint256 amount); // Locations of each mAsset savings contract mapping(address => ISavingsContractV2) public savingsContracts; mapping(address => IRevenueRecipient) public revenueRecipients; // Time at which last collection was made mapping(address => uint256) public lastPeriodStart; mapping(address => uint256) public lastCollection; mapping(address => uint256) public periodYield; // Amount of collected interest that will be sent to Savings Contract (1e18 = 100%) uint256 private savingsRate; // Streaming liquidated tokens uint256 private immutable DURATION; // measure in days. eg 1 days or 7 days uint256 private constant ONE_DAY = 1 days; uint256 private constant THIRTY_MINUTES = 30 minutes; // Streams bool private streamsFrozen = false; // Liquidator mapping(address => Stream) public liqStream; // Platform mapping(address => Stream) public yieldStream; // Batches are for the platformInterest collection mapping(address => uint256) public override lastBatchCollected; enum StreamType { liquidator, yield } struct Stream { uint256 end; uint256 rate; } constructor( address _nexus, address _mUSD, address _savingsContract, uint256 _savingsRate, uint256 _duration ) PausableModule(_nexus) { _updateSavingsContract(_mUSD, _savingsContract); emit SavingsContractAdded(_mUSD, _savingsContract); savingsRate = _savingsRate; DURATION = _duration; } modifier onlyLiquidator() { require(msg.sender == _liquidator(), "Only liquidator can execute"); _; } modifier whenStreamsNotFrozen() { require(!streamsFrozen, "Streaming is currently frozen"); _; } /*************************************** STATE ****************************************/ /** * @dev Adds a new savings contract * @param _mAsset Address of underlying mAsset * @param _savingsContract Address of the savings contract */ function addSavingsContract(address _mAsset, address _savingsContract) external onlyGovernor { require( address(savingsContracts[_mAsset]) == address(0), "Savings contract already exists" ); _updateSavingsContract(_mAsset, _savingsContract); emit SavingsContractAdded(_mAsset, _savingsContract); } /** * @dev Updates an existing savings contract * @param _mAsset Address of underlying mAsset * @param _savingsContract Address of the savings contract */ function updateSavingsContract(address _mAsset, address _savingsContract) external onlyGovernor { require( address(savingsContracts[_mAsset]) != address(0), "Savings contract does not exist" ); _updateSavingsContract(_mAsset, _savingsContract); emit SavingsContractUpdated(_mAsset, _savingsContract); } function _updateSavingsContract(address _mAsset, address _savingsContract) internal { require(_mAsset != address(0) && _savingsContract != address(0), "Must be valid address"); savingsContracts[_mAsset] = ISavingsContractV2(_savingsContract); IERC20(_mAsset).safeApprove(address(_savingsContract), 0); IERC20(_mAsset).safeApprove(address(_savingsContract), type(uint256).max); } /** * @dev Freezes streaming of mAssets */ function freezeStreams() external onlyGovernor whenStreamsNotFrozen { streamsFrozen = true; emit StreamsFrozen(); } /** * @dev Sets the revenue recipient address * @param _mAsset Address of underlying mAsset * @param _recipient Address of the recipient */ function setRevenueRecipient(address _mAsset, address _recipient) external onlyGovernor { revenueRecipients[_mAsset] = IRevenueRecipient(_recipient); emit RevenueRecipientSet(_mAsset, _recipient); } /** * @dev Sets a new savings rate for interest distribution * @param _savingsRate Rate of savings sent to SavingsContract (100% = 1e18) */ function setSavingsRate(uint256 _savingsRate) external onlyGovernor { // Greater than 60% upto 100% require(_savingsRate >= 6e17 && _savingsRate <= 1e18, "Must be a valid rate"); savingsRate = _savingsRate; emit SavingsRateChanged(_savingsRate); } /** * @dev Allows the liquidator to deposit proceeds from liquidated gov tokens. * Transfers proceeds on a second by second basis to the Savings Contract over 1 week. * @param _mAsset The mAsset to transfer and distribute * @param _liquidated Units of mAsset to distribute */ function depositLiquidation(address _mAsset, uint256 _liquidated) external override whenNotPaused onlyLiquidator whenStreamsNotFrozen { // Collect existing interest to ensure everything is up to date _collectAndDistributeInterest(_mAsset); // transfer liquidated mUSD to here IERC20(_mAsset).safeTransferFrom(_liquidator(), address(this), _liquidated); uint256 leftover = _unstreamedRewards(_mAsset, StreamType.liquidator); _initialiseStream(_mAsset, StreamType.liquidator, _liquidated + leftover, DURATION); emit LiquidatorDeposited(_mAsset, _liquidated); } /** * @dev Collects the platform interest from a given mAsset and then adds capital to the * stream. If there is > 24h left in current stream, just top it up, otherwise reset. * @param _mAsset The mAsset to fetch interest */ function collectAndStreamInterest(address _mAsset) external override whenNotPaused whenStreamsNotFrozen { // Collect existing interest to ensure everything is up to date _collectAndDistributeInterest(_mAsset); uint256 currentTime = block.timestamp; uint256 previousBatch = lastBatchCollected[_mAsset]; uint256 timeSincePreviousBatch = currentTime - previousBatch; require(timeSincePreviousBatch > 6 hours, "Cannot deposit twice in 6 hours"); lastBatchCollected[_mAsset] = currentTime; // Batch collect (uint256 interestCollected, uint256 totalSupply) = IMasset(_mAsset).collectPlatformInterest(); if (interestCollected > 0) { // Validate APY uint256 apy = YieldValidator.validateCollection( totalSupply, interestCollected, timeSincePreviousBatch ); // Get remaining rewards uint256 leftover = _unstreamedRewards(_mAsset, StreamType.yield); _initialiseStream(_mAsset, StreamType.yield, interestCollected + leftover, ONE_DAY); emit InterestCollected(_mAsset, interestCollected, totalSupply, apy); } else { emit InterestCollected(_mAsset, interestCollected, totalSupply, 0); } } /** * @dev Calculates how many rewards from the stream are still to be distributed, from the * last collection time to the end of the stream. * @param _mAsset The mAsset in question * @return leftover The total amount of mAsset that is yet to be collected from a stream */ function _unstreamedRewards(address _mAsset, StreamType _stream) internal view returns (uint256 leftover) { uint256 lastUpdate = lastCollection[_mAsset]; Stream memory stream = _stream == StreamType.liquidator ? liqStream[_mAsset] : yieldStream[_mAsset]; uint256 unclaimedSeconds = 0; if (lastUpdate < stream.end) { unclaimedSeconds = stream.end - lastUpdate; } return unclaimedSeconds * stream.rate; } /** * @dev Simply sets up the stream * @param _mAsset The mAsset in question * @param _amount Amount of units to stream * @param _duration Duration of the stream, from now */ function _initialiseStream( address _mAsset, StreamType _stream, uint256 _amount, uint256 _duration ) internal { uint256 currentTime = block.timestamp; // Distribute reward per second over X seconds uint256 rate = _amount / _duration; uint256 end = currentTime + _duration; if (_stream == StreamType.liquidator) { liqStream[_mAsset] = Stream(end, rate); } else { yieldStream[_mAsset] = Stream(end, rate); } // Reset pool data to enable lastCollection usage twice require(lastCollection[_mAsset] == currentTime, "Stream data must be up to date"); } /*************************************** COLLECTION ****************************************/ /** * @dev Collects interest from a target mAsset and distributes to the SavingsContract. * Applies constraints such that the max APY since the last fee collection cannot * exceed the "MAX_APY" variable. * @param _mAsset mAsset for which the interest should be collected */ function collectAndDistributeInterest(address _mAsset) external override whenNotPaused { _collectAndDistributeInterest(_mAsset); } function _collectAndDistributeInterest(address _mAsset) internal { ISavingsContractV2 savingsContract = savingsContracts[_mAsset]; require(address(savingsContract) != address(0), "Must have a valid savings contract"); // Get collection details uint256 recentPeriodStart = lastPeriodStart[_mAsset]; uint256 previousCollection = lastCollection[_mAsset]; lastCollection[_mAsset] = block.timestamp; // 1. Collect the new interest from the mAsset IMasset mAsset = IMasset(_mAsset); (uint256 interestCollected, uint256 totalSupply) = mAsset.collectInterest(); // 2. Update all the time stamps // Avoid division by 0 by adding a minimum elapsed time of 1 second uint256 timeSincePeriodStart = StableMath.max(1, block.timestamp - recentPeriodStart); uint256 timeSinceLastCollection = StableMath.max(1, block.timestamp - previousCollection); uint256 inflationOperand = interestCollected; // If it has been 30 mins since last collection, reset period data if (timeSinceLastCollection > THIRTY_MINUTES) { lastPeriodStart[_mAsset] = block.timestamp; periodYield[_mAsset] = 0; } // Else if period has elapsed, start a new period from the lastCollection time else if (timeSincePeriodStart > THIRTY_MINUTES) { lastPeriodStart[_mAsset] = previousCollection; periodYield[_mAsset] = interestCollected; } // Else add yield to period yield else { inflationOperand = periodYield[_mAsset] + interestCollected; periodYield[_mAsset] = inflationOperand; } // Add on liquidated uint256 newReward = _unclaimedRewards(_mAsset, previousCollection); // 3. Validate that interest is collected correctly and does not exceed max APY if (interestCollected > 0 || newReward > 0) { require( IERC20(_mAsset).balanceOf(address(this)) >= interestCollected + newReward, "Must receive mUSD" ); uint256 extrapolatedAPY = YieldValidator.validateCollection( totalSupply, inflationOperand, timeSinceLastCollection ); emit InterestCollected(_mAsset, interestCollected, totalSupply, extrapolatedAPY); // 4. Distribute the interest // Calculate the share for savers (95e16 or 95%) uint256 saversShare = (interestCollected + newReward).mulTruncate(savingsRate); // Call depositInterest on contract savingsContract.depositInterest(saversShare); emit InterestDistributed(_mAsset, saversShare); } else { emit InterestCollected(_mAsset, 0, totalSupply, 0); } } /** * @dev Calculates unclaimed rewards from the liquidation stream * @param _mAsset mAsset key * @param _previousCollection Time of previous collection * @return Units of mAsset that have been unlocked for distribution */ function _unclaimedRewards(address _mAsset, uint256 _previousCollection) internal view returns (uint256) { Stream memory liq = liqStream[_mAsset]; uint256 unclaimedSeconds_liq = _unclaimedSeconds(_previousCollection, liq.end); uint256 subtotal_liq = unclaimedSeconds_liq * liq.rate; Stream memory yield = yieldStream[_mAsset]; uint256 unclaimedSeconds_yield = _unclaimedSeconds(_previousCollection, yield.end); uint256 subtotal_yield = unclaimedSeconds_yield * yield.rate; return subtotal_liq + subtotal_yield; } /** * @dev Calculates the seconds of unclaimed rewards, based on period length * @param _lastUpdate Time of last update * @param _end End time of period * @return Seconds of stream that should be compensated */ function _unclaimedSeconds(uint256 _lastUpdate, uint256 _end) internal view returns (uint256) { uint256 currentTime = block.timestamp; uint256 unclaimedSeconds = 0; if (currentTime <= _end) { unclaimedSeconds = currentTime - _lastUpdate; } else if (_lastUpdate < _end) { unclaimedSeconds = _end - _lastUpdate; } return unclaimedSeconds; } /*************************************** Revenue Redistribution ****************************************/ /** * @dev Redistributes the unallocated interest to the saved recipient, allowing * the siphoned assets to be used elsewhere in the system * @param _mAsset mAsset to collect */ function distributeUnallocatedInterest(address _mAsset) external override { IRevenueRecipient recipient = revenueRecipients[_mAsset]; require(address(recipient) != address(0), "Must have valid recipient"); IERC20 mAsset = IERC20(_mAsset); uint256 balance = mAsset.balanceOf(address(this)); uint256 leftover_liq = _unstreamedRewards(_mAsset, StreamType.liquidator); uint256 leftover_yield = _unstreamedRewards(_mAsset, StreamType.yield); uint256 unallocated = balance - leftover_liq - leftover_yield; mAsset.approve(address(recipient), unallocated); recipient.notifyRedistributionAmount(_mAsset, unallocated); emit RevenueRedistributed(_mAsset, address(recipient), unallocated); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_nexus","type":"address"},{"internalType":"address","name":"_mUSD","type":"address"},{"internalType":"address","name":"_savingsContract","type":"address"},{"internalType":"uint256","name":"_savingsRate","type":"uint256"},{"internalType":"uint256","name":"_duration","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"mAsset","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":true,"internalType":"address","name":"mAsset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountSent","type":"uint256"}],"name":"InterestDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"mAsset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LiquidatorDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"mAsset","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"}],"name":"RevenueRecipientSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"mAsset","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RevenueRedistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"mAsset","type":"address"},{"indexed":false,"internalType":"address","name":"savingsContract","type":"address"}],"name":"SavingsContractAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"mAsset","type":"address"},{"indexed":false,"internalType":"address","name":"savingsContract","type":"address"}],"name":"SavingsContractUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newSavingsRate","type":"uint256"}],"name":"SavingsRateChanged","type":"event"},{"anonymous":false,"inputs":[],"name":"StreamsFrozen","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"address","name":"_mAsset","type":"address"},{"internalType":"address","name":"_savingsContract","type":"address"}],"name":"addSavingsContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_mAsset","type":"address"}],"name":"collectAndDistributeInterest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_mAsset","type":"address"}],"name":"collectAndStreamInterest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_mAsset","type":"address"},{"internalType":"uint256","name":"_liquidated","type":"uint256"}],"name":"depositLiquidation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_mAsset","type":"address"}],"name":"distributeUnallocatedInterest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"freezeStreams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastBatchCollected","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastCollection","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastPeriodStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"liqStream","outputs":[{"internalType":"uint256","name":"end","type":"uint256"},{"internalType":"uint256","name":"rate","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":[{"internalType":"address","name":"","type":"address"}],"name":"periodYield","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"revenueRecipients","outputs":[{"internalType":"contract IRevenueRecipient","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"savingsContracts","outputs":[{"internalType":"contract ISavingsContractV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_mAsset","type":"address"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"setRevenueRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_savingsRate","type":"uint256"}],"name":"setSavingsRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_mAsset","type":"address"},{"internalType":"address","name":"_savingsContract","type":"address"}],"name":"updateSavingsContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"yieldStream","outputs":[{"internalType":"uint256","name":"end","type":"uint256"},{"internalType":"uint256","name":"rate","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60c06040526000805460ff199081169091556007805490911690553480156200002757600080fd5b5060405162002690380380620026908339810160408190526200004a91620005f8565b84806001600160a01b038116620000a85760405162461bcd60e51b815260206004820152601560248201527f4e657875732061646472657373206973207a65726f000000000000000000000060448201526064015b60405180910390fd5b60601b6001600160601b031916608052506000805460ff19169055620000cf848462000122565b6040516001600160a01b0384811682528516907f508defc317fd15db2b6ef034d39cf1d5db588a037dbd3515824e4baec4228b6c9060200160405180910390a260069190915560a0525062000715915050565b6001600160a01b038216158015906200014357506001600160a01b03811615155b620001915760405162461bcd60e51b815260206004820152601560248201527f4d7573742062652076616c69642061646472657373000000000000000000000060448201526064016200009f565b6001600160a01b038281166000818152600160209081526040822080546001600160a01b03191694861694909417909355620001d99284919062000204811b62000d6917901c565b6200020081600019846001600160a01b03166200020460201b62000d69179092919060201c565b5050565b801580620002925750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b1580156200025557600080fd5b505afa1580156200026a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000290919062000676565b155b620003065760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e63650000000000000000000060648201526084016200009f565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091526200035e9185916200036316565b505050565b6000620003bf826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166200044160201b62000ec5179092919060201c565b8051909150156200035e5780806020019051810190620003e0919062000654565b6200035e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016200009f565b60606200045284846000856200045c565b90505b9392505050565b606082471015620004bf5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016200009f565b620004ca8562000598565b620005185760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016200009f565b600080866001600160a01b031685876040516200053691906200068f565b60006040518083038185875af1925050503d806000811462000575576040519150601f19603f3d011682016040523d82523d6000602084013e6200057a565b606091505b5090925090506200058d828286620005a2565b979650505050505050565b803b15155b919050565b60608315620005b357508162000455565b825115620005c45782518084602001fd5b8160405162461bcd60e51b81526004016200009f9190620006ad565b80516001600160a01b03811681146200059d57600080fd5b600080600080600060a0868803121562000610578081fd5b6200061b86620005e0565b94506200062b60208701620005e0565b93506200063b60408701620005e0565b6060870151608090970151959894975095949392505050565b60006020828403121562000666578081fd5b8151801515811462000455578182fd5b60006020828403121562000688578081fd5b5051919050565b60008251620006a3818460208701620006e2565b9190910192915050565b6000602082528251806020840152620006ce816040850160208701620006e2565b601f01601f19169190910160400192915050565b60005b83811015620006ff578181015183820152602001620006e5565b838111156200070f576000848401525b50505050565b60805160601c60a051611f446200074c60003960006108ce01526000818161027c015281816110fd015261192c0152611f446000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c80638456cb59116100b8578063c02d7b171161007c578063c02d7b17146102da578063ca2bdfe614610316578063cf299ea914610329578063d176d5f714610350578063d536818814610370578063e81441921461038357610137565b80638456cb591461024f578063882111fc14610257578063a3f5c1d214610277578063ac431d7a1461029e578063b75d7607146102b157610137565b806340ed7333116100ff57806340ed7333146101b25780634fa369c4146101f35780635c975abb14610206578063691ef6631461021c578063717f2bc11461023c57610137565b806321aec84a1461013c5780633022dfeb1461015157806333bda1f7146101645780633be22149146101975780633f4ba83a146101aa575b600080fd5b61014f61014a366004611c6b565b61038b565b005b61014f61015f366004611ca3565b6105e3565b610184610172366004611c6b565b600a6020526000908152604090205481565b6040519081526020015b60405180910390f35b61014f6101a5366004611d26565b6106a2565b61014f610748565b6101db6101c0366004611c6b565b6002602052600090815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200161018e565b61014f610201366004611cdb565b6107d9565b60005460ff16604051901515815260200161018e565b61018461022a366004611c6b565b60036020526000908152604090205481565b61014f61024a366004611ca3565b61093a565b61014f6109f0565b610184610265366004611c6b565b60056020526000908152604090205481565b6101db7f000000000000000000000000000000000000000000000000000000000000000081565b61014f6102ac366004611c6b565b610a58565b6101db6102bf366004611c6b565b6001602052600090815260409020546001600160a01b031681565b6103016102e8366004611c6b565b6009602052600090815260409020805460019091015482565b6040805192835260208301919091520161018e565b61014f610324366004611c6b565b610c6f565b610301610337366004611c6b565b6008602052600090815260409020805460019091015482565b61018461035e366004611c6b565b60046020526000908152604090205481565b61014f61037e366004611ca3565b610c9e565b61014f610d06565b6001600160a01b0380821660009081526002602052604090205416806103f85760405162461bcd60e51b815260206004820152601960248201527f4d75737420686176652076616c696420726563697069656e740000000000000060448201526064015b60405180910390fd5b6040516370a0823160e01b815230600482015282906000906001600160a01b038316906370a082319060240160206040518083038186803b15801561043c57600080fd5b505afa158015610450573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104749190611d3e565b90506000610483856000610ede565b90506000610492866001610ede565b90506000816104a18486611e80565b6104ab9190611e80565b60405163095ea7b360e01b81526001600160a01b038881166004830152602482018390529192509086169063095ea7b390604401602060405180830381600087803b1580156104f957600080fd5b505af115801561050d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105319190611d06565b5060405163383680c360e11b81526001600160a01b0388811660048301526024820183905287169063706d018690604401600060405180830381600087803b15801561057c57600080fd5b505af1158015610590573d6000803e3d6000fd5b5050604080516001600160a01b038a81168252602082018690528b1693507f25f038afe3b508b51eefbd7cb74df863b1f311ff2e404467a4223bdb353dcce492500160405180910390a250505050505050565b6105eb610fa3565b6001600160a01b0382811660009081526001602052604090205416156106535760405162461bcd60e51b815260206004820152601f60248201527f536176696e677320636f6e747261637420616c7265616479206578697374730060448201526064016103ef565b61065d828261100d565b6040516001600160a01b0382811682528316907f508defc317fd15db2b6ef034d39cf1d5db588a037dbd3515824e4baec4228b6c906020015b60405180910390a25050565b6106aa610fa3565b670853a0d2313c000081101580156106ca5750670de0b6b3a76400008111155b61070d5760405162461bcd60e51b81526020600482015260146024820152734d75737420626520612076616c6964207261746560601b60448201526064016103ef565b60068190556040518181527faedfe3437b11d6c786a86e8c27ef98816e4fd031ee0613a4e5132ae857065e479060200160405180910390a150565b610750610fa3565b60005460ff166107995760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016103ef565b6000805460ff191690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60005460ff16156107fc5760405162461bcd60e51b81526004016103ef90611dff565b6108046110c5565b6001600160a01b0316336001600160a01b0316146108645760405162461bcd60e51b815260206004820152601b60248201527f4f6e6c79206c697175696461746f722063616e2065786563757465000000000060448201526064016103ef565b60075460ff16156108875760405162461bcd60e51b81526004016103ef90611dc8565b61089082611184565b6108ad61089b6110c5565b6001600160a01b0384169030846115a9565b60006108ba836000610ede565b90506108f28360006108cc8486611e29565b7f00000000000000000000000000000000000000000000000000000000000000006115e7565b826001600160a01b03167f2031d123851984662d738ba6c766d26c120f8030f44ee35ab4ba0a784f7c71a78360405161092d91815260200190565b60405180910390a2505050565b610942610fa3565b6001600160a01b03828116600090815260016020526040902054166109a95760405162461bcd60e51b815260206004820152601f60248201527f536176696e677320636f6e747261637420646f6573206e6f742065786973740060448201526064016103ef565b6109b3828261100d565b6040516001600160a01b0382811682528316907fa1f7f49e41e6da12e99cafaf80f4fd0a1a5dbd92eca85369d5597a1c140b5eab90602001610696565b6109f8610fa3565b60005460ff1615610a1b5760405162461bcd60e51b81526004016103ef90611dff565b6000805460ff191660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258906020016107cf565b60005460ff1615610a7b5760405162461bcd60e51b81526004016103ef90611dff565b60075460ff1615610a9e5760405162461bcd60e51b81526004016103ef90611dc8565b610aa781611184565b6001600160a01b0381166000908152600a60205260408120544291610acc8284611e80565b90506154608111610b1f5760405162461bcd60e51b815260206004820152601f60248201527f43616e6e6f74206465706f73697420747769636520696e203620686f7572730060448201526064016103ef565b6001600160a01b0384166000818152600a60205260408082208690558051633f4480f560e11b81528151929384939092637e8901ea926004808201939182900301818787803b158015610b7157600080fd5b505af1158015610b85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ba99190611d56565b90925090508115610c2c576000610bc1828486611710565b90506000610bd0886001610ede565b9050610beb886001610be28488611e29565b620151806115e7565b60408051858152602081018590529081018390526001600160a01b03891690600080516020611eef8339815191529060600160405180910390a25050610c67565b604080518381526020810183905260008183015290516001600160a01b03881691600080516020611eef833981519152919081900360600190a25b505050505050565b60005460ff1615610c925760405162461bcd60e51b81526004016103ef90611dff565b610c9b81611184565b50565b610ca6610fa3565b6001600160a01b0382811660008181526002602090815260409182902080546001600160a01b0319169486169485179055905192835290917f8fca8811c9f2b99f3c43f36b80aedd3efebd97855e8fbb620f427806b0d257b19101610696565b610d0e610fa3565b60075460ff1615610d315760405162461bcd60e51b81526004016103ef90611dc8565b6007805460ff191660011790556040517fd91af312a230e76188294986220b0a066629d876bbbbc3b060d59499e6f750bf90600090a1565b801580610df25750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b158015610db857600080fd5b505afa158015610dcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df09190611d3e565b155b610e5d5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b60648201526084016103ef565b6040516001600160a01b038316602482015260448101829052610ec090849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261172e565b505050565b6060610ed48484600085611800565b90505b9392505050565b6001600160a01b0382166000908152600460205260408120548180846001811115610f1957634e487b7160e01b600052602160045260246000fd5b14610f3b576001600160a01b0385166000908152600960205260409020610f54565b6001600160a01b03851660009081526008602052604090205b60408051808201909152815480825260019092015460208201529150600090831015610f8a578151610f87908490611e80565b90505b6020820151610f999082611e61565b9695505050505050565b610fab611928565b6001600160a01b0316336001600160a01b03161461100b5760405162461bcd60e51b815260206004820152601960248201527f4f6e6c7920676f7665726e6f722063616e20657865637574650000000000000060448201526064016103ef565b565b6001600160a01b0382161580159061102d57506001600160a01b03811615155b6110715760405162461bcd60e51b81526020600482015260156024820152744d7573742062652076616c6964206164647265737360581b60448201526064016103ef565b6001600160a01b03828116600081815260016020526040812080546001600160a01b031916938516939093179092556110ab918390610d69565b6110c16001600160a01b03831682600019610d69565b5050565b6040516385acd64160e01b81527f1e9cb14d7560734a61fa5ff9273953e971ff3cd9283c03d8346e3264617933d460048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906385acd6419060240160206040518083038186803b15801561114757600080fd5b505afa15801561115b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117f9190611c87565b905090565b6001600160a01b0380821660009081526001602052604090205416806111f75760405162461bcd60e51b815260206004820152602260248201527f4d757374206861766520612076616c696420736176696e677320636f6e74726160448201526118dd60f21b60648201526084016103ef565b6001600160a01b0382166000818152600360209081526040808320546004928390528184208054429091558251631517d59160e11b8152835192969195899590948594632a2fab2293808401939082900301818787803b15801561125a57600080fd5b505af115801561126e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112929190611d56565b909250905060006112ad60016112a88842611e80565b611983565b905060006112c060016112a88842611e80565b9050836107088211156112f8576001600160a01b038a1660009081526003602090815260408083204290556005909152812055611371565b61070883111561132f576001600160a01b038a1660009081526003602090815260408083208a905560059091529020859055611371565b6001600160a01b038a16600090815260056020526040902054611353908690611e29565b6001600160a01b038b16600090815260056020526040902081905590505b600061137d8b89611999565b9050600086118061138e5750600081115b156115615761139d8187611e29565b6040516370a0823160e01b81523060048201526001600160a01b038d16906370a082319060240160206040518083038186803b1580156113dc57600080fd5b505afa1580156113f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114149190611d3e565b10156114565760405162461bcd60e51b8152602060048201526011602482015270135d5cdd081c9958d95a5d99481b5554d1607a1b60448201526064016103ef565b6000611463868486611710565b60408051898152602081018990529081018290529091506001600160a01b038d1690600080516020611eef8339815191529060600160405180910390a260006114ba600654848a6114b49190611e29565b90611a60565b60405163220c5bbb60e01b8152600481018290529091506001600160a01b038d169063220c5bbb90602401600060405180830381600087803b1580156114ff57600080fd5b505af1158015611513573d6000803e3d6000fd5b505050508c6001600160a01b03167fffbd5470d1efa00ab4b8be8ae04ba319ee7926ffe943a91b8af15bea044ceaf38260405161155291815260200190565b60405180910390a2505061159c565b604080516000808252602082018890528183015290516001600160a01b038d1691600080516020611eef833981519152919081900360600190a25b5050505050505050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526115e19085906323b872dd60e01b90608401610e89565b50505050565b4260006115f48385611e41565b905060006116028484611e29565b9050600086600181111561162657634e487b7160e01b600052602160045260246000fd5b14156116685760408051808201825282815260208082018581526001600160a01b038b16600090815260089092529290209051815590516001909101556116a0565b60408051808201825282815260208082018581526001600160a01b038b16600090815260099092529290209051815590516001909101555b6001600160a01b03871660009081526004602052604090205483146117075760405162461bcd60e51b815260206004820152601e60248201527f53747265616d2064617461206d75737420626520757020746f2064617465000060448201526064016103ef565b50505050505050565b6000610ed484848467d02ab486cedc000066038d7ea4c68000611a75565b6000611783826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610ec59092919063ffffffff16565b805190915015610ec057808060200190518101906117a19190611d06565b610ec05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016103ef565b6060824710156118615760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016103ef565b843b6118af5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103ef565b600080866001600160a01b031685876040516118cb9190611d79565b60006040518083038185875af1925050503d8060008114611908576040519150601f19603f3d011682016040523d82523d6000602084013e61190d565b606091505b509150915061191d828286611be2565b979650505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b15801561114757600080fd5b60008183116119925781610ed7565b5090919050565b6001600160a01b038216600090815260086020908152604080832081518083019092528054808352600190910154928201929092529082906119dc908590611c1b565b905060008260200151826119f09190611e61565b6001600160a01b03871660009081526009602090815260408083208151808301909252805480835260019091015492820192909252929350611a33908890611c1b565b90506000826020015182611a479190611e61565b9050611a538185611e29565b9998505050505050505050565b6000610ed78383670de0b6b3a7640000611c54565b6000808415611a845784611a87565b60015b90506000611a958789611e80565b9050600081611aac89670de0b6b3a7640000611e61565b611ab69190611e41565b905060006301e13380611ad185670de0b6b3a7640000611e61565b611adb9190611e41565b905080611af083670de0b6b3a7640000611e61565b611afa9190611e41565b9450610708841115611b7057868510611b6b5760405162461bcd60e51b815260206004820152602d60248201527f496e7465726573742070726f7465637465642066726f6d20696e666c6174696e60448201526c672070617374206d617841505960981b60648201526084016103ef565b611bd5565b858210611bd55760405162461bcd60e51b815260206004820152602d60248201527f496e7465726573742070726f7465637465642066726f6d20696e666c6174696e60448201526c6720706173742031302042707360981b60648201526084016103ef565b5050505095945050505050565b60608315611bf1575081610ed7565b825115611c015782518084602001fd5b8160405162461bcd60e51b81526004016103ef9190611d95565b60004281838211611c3757611c308583611e80565b9050611c4c565b83851015611c4c57611c498585611e80565b90505b949350505050565b600081611c618486611e61565b610ed49190611e41565b600060208284031215611c7c578081fd5b8135610ed781611ed9565b600060208284031215611c98578081fd5b8151610ed781611ed9565b60008060408385031215611cb5578081fd5b8235611cc081611ed9565b91506020830135611cd081611ed9565b809150509250929050565b60008060408385031215611ced578182fd5b8235611cf881611ed9565b946020939093013593505050565b600060208284031215611d17578081fd5b81518015158114610ed7578182fd5b600060208284031215611d37578081fd5b5035919050565b600060208284031215611d4f578081fd5b5051919050565b60008060408385031215611d68578182fd5b505080516020909101519092909150565b60008251611d8b818460208701611e97565b9190910192915050565b6000602082528251806020840152611db4816040850160208701611e97565b601f01601f19169190910160400192915050565b6020808252601d908201527f53747265616d696e672069732063757272656e746c792066726f7a656e000000604082015260600190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b60008219821115611e3c57611e3c611ec3565b500190565b600082611e5c57634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615611e7b57611e7b611ec3565b500290565b600082821015611e9257611e92611ec3565b500390565b60005b83811015611eb2578181015183820152602001611e9a565b838111156115e15750506000910152565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b0381168114610c9b57600080fdfe0abcfa9ece819bcdcfa052a818ce11f0b9fad8b3e3ccd98f120c40be689b690fa264697066735822122083e7f1d2b8388b7a75e9e2e56270159639d5940256eb6f0ae499255ad51e29cb64736f6c634300080200330000000000000000000000003c6fbb8cbfcb75ecec5128e9f73307f2cb33f2f6000000000000000000000000e840b73e5287865eec17d250bfb1536704b43b210000000000000000000000005290ad3d83476ca6a2b178cd9727ee1ef72432af0000000000000000000000000000000000000000000000000c7d713b49da00000000000000000000000000000000000000000000000000000000000000015180
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101375760003560e01c80638456cb59116100b8578063c02d7b171161007c578063c02d7b17146102da578063ca2bdfe614610316578063cf299ea914610329578063d176d5f714610350578063d536818814610370578063e81441921461038357610137565b80638456cb591461024f578063882111fc14610257578063a3f5c1d214610277578063ac431d7a1461029e578063b75d7607146102b157610137565b806340ed7333116100ff57806340ed7333146101b25780634fa369c4146101f35780635c975abb14610206578063691ef6631461021c578063717f2bc11461023c57610137565b806321aec84a1461013c5780633022dfeb1461015157806333bda1f7146101645780633be22149146101975780633f4ba83a146101aa575b600080fd5b61014f61014a366004611c6b565b61038b565b005b61014f61015f366004611ca3565b6105e3565b610184610172366004611c6b565b600a6020526000908152604090205481565b6040519081526020015b60405180910390f35b61014f6101a5366004611d26565b6106a2565b61014f610748565b6101db6101c0366004611c6b565b6002602052600090815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200161018e565b61014f610201366004611cdb565b6107d9565b60005460ff16604051901515815260200161018e565b61018461022a366004611c6b565b60036020526000908152604090205481565b61014f61024a366004611ca3565b61093a565b61014f6109f0565b610184610265366004611c6b565b60056020526000908152604090205481565b6101db7f0000000000000000000000003c6fbb8cbfcb75ecec5128e9f73307f2cb33f2f681565b61014f6102ac366004611c6b565b610a58565b6101db6102bf366004611c6b565b6001602052600090815260409020546001600160a01b031681565b6103016102e8366004611c6b565b6009602052600090815260409020805460019091015482565b6040805192835260208301919091520161018e565b61014f610324366004611c6b565b610c6f565b610301610337366004611c6b565b6008602052600090815260409020805460019091015482565b61018461035e366004611c6b565b60046020526000908152604090205481565b61014f61037e366004611ca3565b610c9e565b61014f610d06565b6001600160a01b0380821660009081526002602052604090205416806103f85760405162461bcd60e51b815260206004820152601960248201527f4d75737420686176652076616c696420726563697069656e740000000000000060448201526064015b60405180910390fd5b6040516370a0823160e01b815230600482015282906000906001600160a01b038316906370a082319060240160206040518083038186803b15801561043c57600080fd5b505afa158015610450573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104749190611d3e565b90506000610483856000610ede565b90506000610492866001610ede565b90506000816104a18486611e80565b6104ab9190611e80565b60405163095ea7b360e01b81526001600160a01b038881166004830152602482018390529192509086169063095ea7b390604401602060405180830381600087803b1580156104f957600080fd5b505af115801561050d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105319190611d06565b5060405163383680c360e11b81526001600160a01b0388811660048301526024820183905287169063706d018690604401600060405180830381600087803b15801561057c57600080fd5b505af1158015610590573d6000803e3d6000fd5b5050604080516001600160a01b038a81168252602082018690528b1693507f25f038afe3b508b51eefbd7cb74df863b1f311ff2e404467a4223bdb353dcce492500160405180910390a250505050505050565b6105eb610fa3565b6001600160a01b0382811660009081526001602052604090205416156106535760405162461bcd60e51b815260206004820152601f60248201527f536176696e677320636f6e747261637420616c7265616479206578697374730060448201526064016103ef565b61065d828261100d565b6040516001600160a01b0382811682528316907f508defc317fd15db2b6ef034d39cf1d5db588a037dbd3515824e4baec4228b6c906020015b60405180910390a25050565b6106aa610fa3565b670853a0d2313c000081101580156106ca5750670de0b6b3a76400008111155b61070d5760405162461bcd60e51b81526020600482015260146024820152734d75737420626520612076616c6964207261746560601b60448201526064016103ef565b60068190556040518181527faedfe3437b11d6c786a86e8c27ef98816e4fd031ee0613a4e5132ae857065e479060200160405180910390a150565b610750610fa3565b60005460ff166107995760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016103ef565b6000805460ff191690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60005460ff16156107fc5760405162461bcd60e51b81526004016103ef90611dff565b6108046110c5565b6001600160a01b0316336001600160a01b0316146108645760405162461bcd60e51b815260206004820152601b60248201527f4f6e6c79206c697175696461746f722063616e2065786563757465000000000060448201526064016103ef565b60075460ff16156108875760405162461bcd60e51b81526004016103ef90611dc8565b61089082611184565b6108ad61089b6110c5565b6001600160a01b0384169030846115a9565b60006108ba836000610ede565b90506108f28360006108cc8486611e29565b7f00000000000000000000000000000000000000000000000000000000000151806115e7565b826001600160a01b03167f2031d123851984662d738ba6c766d26c120f8030f44ee35ab4ba0a784f7c71a78360405161092d91815260200190565b60405180910390a2505050565b610942610fa3565b6001600160a01b03828116600090815260016020526040902054166109a95760405162461bcd60e51b815260206004820152601f60248201527f536176696e677320636f6e747261637420646f6573206e6f742065786973740060448201526064016103ef565b6109b3828261100d565b6040516001600160a01b0382811682528316907fa1f7f49e41e6da12e99cafaf80f4fd0a1a5dbd92eca85369d5597a1c140b5eab90602001610696565b6109f8610fa3565b60005460ff1615610a1b5760405162461bcd60e51b81526004016103ef90611dff565b6000805460ff191660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258906020016107cf565b60005460ff1615610a7b5760405162461bcd60e51b81526004016103ef90611dff565b60075460ff1615610a9e5760405162461bcd60e51b81526004016103ef90611dc8565b610aa781611184565b6001600160a01b0381166000908152600a60205260408120544291610acc8284611e80565b90506154608111610b1f5760405162461bcd60e51b815260206004820152601f60248201527f43616e6e6f74206465706f73697420747769636520696e203620686f7572730060448201526064016103ef565b6001600160a01b0384166000818152600a60205260408082208690558051633f4480f560e11b81528151929384939092637e8901ea926004808201939182900301818787803b158015610b7157600080fd5b505af1158015610b85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ba99190611d56565b90925090508115610c2c576000610bc1828486611710565b90506000610bd0886001610ede565b9050610beb886001610be28488611e29565b620151806115e7565b60408051858152602081018590529081018390526001600160a01b03891690600080516020611eef8339815191529060600160405180910390a25050610c67565b604080518381526020810183905260008183015290516001600160a01b03881691600080516020611eef833981519152919081900360600190a25b505050505050565b60005460ff1615610c925760405162461bcd60e51b81526004016103ef90611dff565b610c9b81611184565b50565b610ca6610fa3565b6001600160a01b0382811660008181526002602090815260409182902080546001600160a01b0319169486169485179055905192835290917f8fca8811c9f2b99f3c43f36b80aedd3efebd97855e8fbb620f427806b0d257b19101610696565b610d0e610fa3565b60075460ff1615610d315760405162461bcd60e51b81526004016103ef90611dc8565b6007805460ff191660011790556040517fd91af312a230e76188294986220b0a066629d876bbbbc3b060d59499e6f750bf90600090a1565b801580610df25750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b158015610db857600080fd5b505afa158015610dcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df09190611d3e565b155b610e5d5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b60648201526084016103ef565b6040516001600160a01b038316602482015260448101829052610ec090849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261172e565b505050565b6060610ed48484600085611800565b90505b9392505050565b6001600160a01b0382166000908152600460205260408120548180846001811115610f1957634e487b7160e01b600052602160045260246000fd5b14610f3b576001600160a01b0385166000908152600960205260409020610f54565b6001600160a01b03851660009081526008602052604090205b60408051808201909152815480825260019092015460208201529150600090831015610f8a578151610f87908490611e80565b90505b6020820151610f999082611e61565b9695505050505050565b610fab611928565b6001600160a01b0316336001600160a01b03161461100b5760405162461bcd60e51b815260206004820152601960248201527f4f6e6c7920676f7665726e6f722063616e20657865637574650000000000000060448201526064016103ef565b565b6001600160a01b0382161580159061102d57506001600160a01b03811615155b6110715760405162461bcd60e51b81526020600482015260156024820152744d7573742062652076616c6964206164647265737360581b60448201526064016103ef565b6001600160a01b03828116600081815260016020526040812080546001600160a01b031916938516939093179092556110ab918390610d69565b6110c16001600160a01b03831682600019610d69565b5050565b6040516385acd64160e01b81527f1e9cb14d7560734a61fa5ff9273953e971ff3cd9283c03d8346e3264617933d460048201526000907f0000000000000000000000003c6fbb8cbfcb75ecec5128e9f73307f2cb33f2f66001600160a01b0316906385acd6419060240160206040518083038186803b15801561114757600080fd5b505afa15801561115b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117f9190611c87565b905090565b6001600160a01b0380821660009081526001602052604090205416806111f75760405162461bcd60e51b815260206004820152602260248201527f4d757374206861766520612076616c696420736176696e677320636f6e74726160448201526118dd60f21b60648201526084016103ef565b6001600160a01b0382166000818152600360209081526040808320546004928390528184208054429091558251631517d59160e11b8152835192969195899590948594632a2fab2293808401939082900301818787803b15801561125a57600080fd5b505af115801561126e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112929190611d56565b909250905060006112ad60016112a88842611e80565b611983565b905060006112c060016112a88842611e80565b9050836107088211156112f8576001600160a01b038a1660009081526003602090815260408083204290556005909152812055611371565b61070883111561132f576001600160a01b038a1660009081526003602090815260408083208a905560059091529020859055611371565b6001600160a01b038a16600090815260056020526040902054611353908690611e29565b6001600160a01b038b16600090815260056020526040902081905590505b600061137d8b89611999565b9050600086118061138e5750600081115b156115615761139d8187611e29565b6040516370a0823160e01b81523060048201526001600160a01b038d16906370a082319060240160206040518083038186803b1580156113dc57600080fd5b505afa1580156113f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114149190611d3e565b10156114565760405162461bcd60e51b8152602060048201526011602482015270135d5cdd081c9958d95a5d99481b5554d1607a1b60448201526064016103ef565b6000611463868486611710565b60408051898152602081018990529081018290529091506001600160a01b038d1690600080516020611eef8339815191529060600160405180910390a260006114ba600654848a6114b49190611e29565b90611a60565b60405163220c5bbb60e01b8152600481018290529091506001600160a01b038d169063220c5bbb90602401600060405180830381600087803b1580156114ff57600080fd5b505af1158015611513573d6000803e3d6000fd5b505050508c6001600160a01b03167fffbd5470d1efa00ab4b8be8ae04ba319ee7926ffe943a91b8af15bea044ceaf38260405161155291815260200190565b60405180910390a2505061159c565b604080516000808252602082018890528183015290516001600160a01b038d1691600080516020611eef833981519152919081900360600190a25b5050505050505050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526115e19085906323b872dd60e01b90608401610e89565b50505050565b4260006115f48385611e41565b905060006116028484611e29565b9050600086600181111561162657634e487b7160e01b600052602160045260246000fd5b14156116685760408051808201825282815260208082018581526001600160a01b038b16600090815260089092529290209051815590516001909101556116a0565b60408051808201825282815260208082018581526001600160a01b038b16600090815260099092529290209051815590516001909101555b6001600160a01b03871660009081526004602052604090205483146117075760405162461bcd60e51b815260206004820152601e60248201527f53747265616d2064617461206d75737420626520757020746f2064617465000060448201526064016103ef565b50505050505050565b6000610ed484848467d02ab486cedc000066038d7ea4c68000611a75565b6000611783826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610ec59092919063ffffffff16565b805190915015610ec057808060200190518101906117a19190611d06565b610ec05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016103ef565b6060824710156118615760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016103ef565b843b6118af5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103ef565b600080866001600160a01b031685876040516118cb9190611d79565b60006040518083038185875af1925050503d8060008114611908576040519150601f19603f3d011682016040523d82523d6000602084013e61190d565b606091505b509150915061191d828286611be2565b979650505050505050565b60007f0000000000000000000000003c6fbb8cbfcb75ecec5128e9f73307f2cb33f2f66001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b15801561114757600080fd5b60008183116119925781610ed7565b5090919050565b6001600160a01b038216600090815260086020908152604080832081518083019092528054808352600190910154928201929092529082906119dc908590611c1b565b905060008260200151826119f09190611e61565b6001600160a01b03871660009081526009602090815260408083208151808301909252805480835260019091015492820192909252929350611a33908890611c1b565b90506000826020015182611a479190611e61565b9050611a538185611e29565b9998505050505050505050565b6000610ed78383670de0b6b3a7640000611c54565b6000808415611a845784611a87565b60015b90506000611a958789611e80565b9050600081611aac89670de0b6b3a7640000611e61565b611ab69190611e41565b905060006301e13380611ad185670de0b6b3a7640000611e61565b611adb9190611e41565b905080611af083670de0b6b3a7640000611e61565b611afa9190611e41565b9450610708841115611b7057868510611b6b5760405162461bcd60e51b815260206004820152602d60248201527f496e7465726573742070726f7465637465642066726f6d20696e666c6174696e60448201526c672070617374206d617841505960981b60648201526084016103ef565b611bd5565b858210611bd55760405162461bcd60e51b815260206004820152602d60248201527f496e7465726573742070726f7465637465642066726f6d20696e666c6174696e60448201526c6720706173742031302042707360981b60648201526084016103ef565b5050505095945050505050565b60608315611bf1575081610ed7565b825115611c015782518084602001fd5b8160405162461bcd60e51b81526004016103ef9190611d95565b60004281838211611c3757611c308583611e80565b9050611c4c565b83851015611c4c57611c498585611e80565b90505b949350505050565b600081611c618486611e61565b610ed49190611e41565b600060208284031215611c7c578081fd5b8135610ed781611ed9565b600060208284031215611c98578081fd5b8151610ed781611ed9565b60008060408385031215611cb5578081fd5b8235611cc081611ed9565b91506020830135611cd081611ed9565b809150509250929050565b60008060408385031215611ced578182fd5b8235611cf881611ed9565b946020939093013593505050565b600060208284031215611d17578081fd5b81518015158114610ed7578182fd5b600060208284031215611d37578081fd5b5035919050565b600060208284031215611d4f578081fd5b5051919050565b60008060408385031215611d68578182fd5b505080516020909101519092909150565b60008251611d8b818460208701611e97565b9190910192915050565b6000602082528251806020840152611db4816040850160208701611e97565b601f01601f19169190910160400192915050565b6020808252601d908201527f53747265616d696e672069732063757272656e746c792066726f7a656e000000604082015260600190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b60008219821115611e3c57611e3c611ec3565b500190565b600082611e5c57634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615611e7b57611e7b611ec3565b500290565b600082821015611e9257611e92611ec3565b500390565b60005b83811015611eb2578181015183820152602001611e9a565b838111156115e15750506000910152565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b0381168114610c9b57600080fdfe0abcfa9ece819bcdcfa052a818ce11f0b9fad8b3e3ccd98f120c40be689b690fa264697066735822122083e7f1d2b8388b7a75e9e2e56270159639d5940256eb6f0ae499255ad51e29cb64736f6c63430008020033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000003c6fbb8cbfcb75ecec5128e9f73307f2cb33f2f6000000000000000000000000e840b73e5287865eec17d250bfb1536704b43b210000000000000000000000005290ad3d83476ca6a2b178cd9727ee1ef72432af0000000000000000000000000000000000000000000000000c7d713b49da00000000000000000000000000000000000000000000000000000000000000015180
-----Decoded View---------------
Arg [0] : _nexus (address): 0x3C6fbB8cbfCB75ecEC5128e9f73307f2cB33f2f6
Arg [1] : _mUSD (address): 0xE840B73E5287865EEc17d250bFb1536704B43B21
Arg [2] : _savingsContract (address): 0x5290Ad3d83476CA6A2b178Cd9727eE1EF72432af
Arg [3] : _savingsRate (uint256): 900000000000000000
Arg [4] : _duration (uint256): 86400
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000003c6fbb8cbfcb75ecec5128e9f73307f2cb33f2f6
Arg [1] : 000000000000000000000000e840b73e5287865eec17d250bfb1536704b43b21
Arg [2] : 0000000000000000000000005290ad3d83476ca6a2b178cd9727ee1ef72432af
Arg [3] : 0000000000000000000000000000000000000000000000000c7d713b49da0000
Arg [4] : 0000000000000000000000000000000000000000000000000000000000015180
Deployed Bytecode Sourcemap
37745:16256:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53216:782;;;;;;:::i;:::-;;:::i;:::-;;40800:364;;;;;;:::i;:::-;;:::i;39654:62::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;4024:25:1;;;4012:2;3997:18;39654:62:0;;;;;;;;42986:288;;;;;;:::i;:::-;;:::i;12850:122::-;;;:::i;38772:62::-;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;38772:62:0;;;;;;-1:-1:-1;;;;;2674:32:1;;;2656:51;;2644:2;2629:18;38772:62:0;2611:102:1;43593:682:0;;;;;;:::i;:::-;;:::i;12459:80::-;12500:4;12524:7;;;12459:80;;3851:14:1;;3844:22;3826:41;;3814:2;3799:18;12459:80:0;3781:92:1;38888:50:0;;;;;;:::i;:::-;;;;;;;;;;;;;;41367:392;;;;;;:::i;:::-;;:::i;12635:120::-;;;:::i;39001:46::-;;;;;;:::i;:::-;;;;;;;;;;;;;;8741:29;;;;;44537:1440;;;;;;:::i;:::-;;:::i;38703:62::-;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;38703:62:0;;;39546:45;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;13263:25:1;;;13319:2;13304:18;;13297:34;;;;13236:18;39546:45:0;13218:119:1;48190:144:0;;;;;;:::i;:::-;;:::i;39479:43::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;38945:49;;;;;;:::i;:::-;;;;;;;;;;;;;;42590:223;;;;;;:::i;:::-;;:::i;42256:140::-;;;:::i;53216:782::-;-1:-1:-1;;;;;53331:26:0;;;53301:27;53331:26;;;:17;:26;;;;;;;53376:32;53368:70;;;;-1:-1:-1;;;53368:70:0;;10091:2:1;53368:70:0;;;10073:21:1;10130:2;10110:18;;;10103:30;10169:27;10149:18;;;10142:55;10214:18;;53368:70:0;;;;;;;;;53511:31;;-1:-1:-1;;;53511:31:0;;53536:4;53511:31;;;2656:51:1;53474:7:0;;53451:13;;-1:-1:-1;;;;;53511:16:0;;;;;2629:18:1;;53511:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;53493:49;;53553:20;53576:50;53595:7;53604:21;53576:18;:50::i;:::-;53553:73;;53637:22;53662:45;53681:7;53690:16;53662:18;:45::i;:::-;53637:70;-1:-1:-1;53720:19:0;53637:70;53742:22;53752:12;53742:7;:22;:::i;:::-;:39;;;;:::i;:::-;53794:47;;-1:-1:-1;;;53794:47:0;;-1:-1:-1;;;;;3599:32:1;;;53794:47:0;;;3581:51:1;3648:18;;;3641:34;;;53720:61:0;;-1:-1:-1;53794:14:0;;;;;;3554:18:1;;53794:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;53852:58:0;;-1:-1:-1;;;53852:58:0;;-1:-1:-1;;;;;3599:32:1;;;53852:58:0;;;3581:51:1;3648:18;;;3641:34;;;53852:36:0;;;;;3554:18:1;;53852:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;53928:62:0;;;-1:-1:-1;;;;;3599:32:1;;;3581:51;;3663:2;3648:18;;3641:34;;;53928:62:0;;;-1:-1:-1;53928:62:0;;-1:-1:-1;3554:18:1;53928:62:0;;;;;;;53216:782;;;;;;;:::o;40800:364::-;9175:15;:13;:15::i;:::-;-1:-1:-1;;;;;40934:25:0;;::::1;40972:1;40934:25:::0;;;:16:::1;:25;::::0;;;;;::::1;40926:48:::0;40904:129:::1;;;::::0;-1:-1:-1;;;40904:129:0;;9731:2:1;40904:129:0::1;::::0;::::1;9713:21:1::0;9770:2;9750:18;;;9743:30;9809:33;9789:18;;;9782:61;9860:18;;40904:129:0::1;9703:181:1::0;40904:129:0::1;41044:49;41067:7;41076:16;41044:22;:49::i;:::-;41109:47;::::0;-1:-1:-1;;;;;2674:32:1;;;2656:51;;41109:47:0;::::1;::::0;::::1;::::0;2644:2:1;2629:18;41109:47:0::1;;;;;;;;40800:364:::0;;:::o;42986:288::-;9175:15;:13;:15::i;:::-;43128:4:::1;43112:12;:20;;:44;;;;;43152:4;43136:12;:20;;43112:44;43104:77;;;::::0;-1:-1:-1;;;43104:77:0;;10445:2:1;43104:77:0::1;::::0;::::1;10427:21:1::0;10484:2;10464:18;;;10457:30;-1:-1:-1;;;10503:18:1;;;10496:50;10563:18;;43104:77:0::1;10417:170:1::0;43104:77:0::1;43192:11;:26:::0;;;43234:32:::1;::::0;4024:25:1;;;43234:32:0::1;::::0;4012:2:1;3997:18;43234:32:0::1;;;;;;;42986:288:::0;:::o;12850:122::-;9175:15;:13;:15::i;:::-;11963:7:::1;::::0;::::1;;11955:40;;;::::0;-1:-1:-1;;;11955:40:0;;6037:2:1;11955:40:0::1;::::0;::::1;6019:21:1::0;6076:2;6056:18;;;6049:30;-1:-1:-1;;;6095:18:1;;;6088:50;6155:18;;11955:40:0::1;6009:170:1::0;11955:40:0::1;12923:5:::2;12913:15:::0;;-1:-1:-1;;12913:15:0::2;::::0;;12944:20:::2;::::0;12953:10:::2;2656:51:1::0;;12944:20:0::2;::::0;2644:2:1;2629:18;12944:20:0::2;;;;;;;;12850:122::o:0;43593:682::-;11764:7;;;;11763:8;11755:37;;;;-1:-1:-1;;;11755:37:0;;;;;;;:::i;:::-;40292:13:::1;:11;:13::i;:::-;-1:-1:-1::0;;;;;40278:27:0::1;:10;-1:-1:-1::0;;;;;40278:27:0::1;;40270:67;;;::::0;-1:-1:-1;;;40270:67:0;;9015:2:1;40270:67:0::1;::::0;::::1;8997:21:1::0;9054:2;9034:18;;;9027:30;9093:29;9073:18;;;9066:57;9140:18;;40270:67:0::1;8987:177:1::0;40270:67:0::1;40417:13:::2;::::0;::::2;;40416:14;40408:56;;;;-1:-1:-1::0;;;40408:56:0::2;;;;;;;:::i;:::-;43861:38:::3;43891:7;43861:29;:38::i;:::-;43957:75;43990:13;:11;:13::i;:::-;-1:-1:-1::0;;;;;43957:32:0;::::3;::::0;44013:4:::3;44020:11:::0;43957:32:::3;:75::i;:::-;44045:16;44064:50;44083:7;44092:21;44064:18;:50::i;:::-;44045:69:::0;-1:-1:-1;44125:83:0::3;44143:7:::0;44152:21:::3;44175:22;44045:69:::0;44175:11;:22:::3;:::i;:::-;44199:8;44125:17;:83::i;:::-;44246:7;-1:-1:-1::0;;;;;44226:41:0::3;;44255:11;44226:41;;;;4024:25:1::0;;4012:2;3997:18;;3979:76;44226:41:0::3;;;;;;;;40475:1;43593:682:::0;;:::o;41367:392::-;9175:15;:13;:15::i;:::-;-1:-1:-1;;;;;41527:25:0;;::::1;41565:1;41527:25:::0;;;:16:::1;:25;::::0;;;;;::::1;41497:129;;;::::0;-1:-1:-1;;;41497:129:0;;9371:2:1;41497:129:0::1;::::0;::::1;9353:21:1::0;9410:2;9390:18;;;9383:30;9449:33;9429:18;;;9422:61;9500:18;;41497:129:0::1;9343:181:1::0;41497:129:0::1;41637:49;41660:7;41669:16;41637:22;:49::i;:::-;41702;::::0;-1:-1:-1;;;;;2674:32:1;;;2656:51;;41702:49:0;::::1;::::0;::::1;::::0;2644:2:1;2629:18;41702:49:0::1;2611:102:1::0;12635:120:0;9175:15;:13;:15::i;:::-;11764:7:::1;::::0;::::1;;11763:8;11755:37;;;;-1:-1:-1::0;;;11755:37:0::1;;;;;;;:::i;:::-;12699:7:::2;:14:::0;;-1:-1:-1;;12699:14:0::2;12709:4;12699:14;::::0;;12729:18:::2;::::0;12736:10:::2;2656:51:1::0;;12729:18:0::2;::::0;2644:2:1;2629:18;12729::0::2;2611:102:1::0;44537:1440:0;11764:7;;;;11763:8;11755:37;;;;-1:-1:-1;;;11755:37:0;;;;;;;:::i;:::-;40417:13:::1;::::0;::::1;;40416:14;40408:56;;;;-1:-1:-1::0;;;40408:56:0::1;;;;;;;:::i;:::-;44766:38:::2;44796:7;44766:29;:38::i;:::-;-1:-1:-1::0;;;;;44889:27:0;::::2;44817:19;44889:27:::0;;;:18:::2;:27;::::0;;;;;44839:15:::2;::::0;44960:27:::2;44889::::0;44839:15;44960:27:::2;:::i;:::-;44927:60;;45031:7;45006:22;:32;44998:76;;;::::0;-1:-1:-1;;;44998:76:0;;6732:2:1;44998:76:0::2;::::0;::::2;6714:21:1::0;6771:2;6751:18;;;6744:30;6810:33;6790:18;;;6783:61;6861:18;;44998:76:0::2;6704:181:1::0;44998:76:0::2;-1:-1:-1::0;;;;;45085:27:0;::::2;;::::0;;;:18:::2;:27;::::0;;;;;:41;;;45229:42;;-1:-1:-1;;;45229:42:0;;;;45085:27;;;;;;45229:40:::2;::::0;:42:::2;::::0;;::::2;::::0;;;;;;;45085:27;;45229:42;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;45165:106:::0;;-1:-1:-1;45165:106:0;-1:-1:-1;45288:21:0;;45284:686:::2;;45355:11;45386:171;45442:11;45476:17;45516:22;45386:33;:171::i;:::-;45355:202;;45612:16;45631:45;45650:7;45659:16;45631:18;:45::i;:::-;45612:64:::0;-1:-1:-1;45691:83:0::2;45709:7:::0;45718:16:::2;45736:28;45612:64:::0;45736:17;:28:::2;:::i;:::-;39331:6;45691:17;:83::i;:::-;45796:63;::::0;;4967:25:1;;;5023:2;5008:18;;5001:34;;;5051:18;;;5044:34;;;-1:-1:-1;;;;;45796:63:0;::::2;::::0;-1:-1:-1;;;;;;;;;;;45796:63:0;4955:2:1;4940:18;45796:63:0::2;;;;;;;45284:686;;;;;45897:61;::::0;;4967:25:1;;;5023:2;5008:18;;5001:34;;;-1:-1:-1;5051:18:1;;;5044:34;45897:61:0;;-1:-1:-1;;;;;45897:61:0;::::2;::::0;-1:-1:-1;;;;;;;;;;;45897:61:0;;;;;4955:2:1;45897:61:0;;::::2;45284:686;40475:1;;;;;44537:1440:::0;:::o;48190:144::-;11764:7;;;;11763:8;11755:37;;;;-1:-1:-1;;;11755:37:0;;;;;;;:::i;:::-;48288:38:::1;48318:7;48288:29;:38::i;:::-;48190:144:::0;:::o;42590:223::-;9175:15;:13;:15::i;:::-;-1:-1:-1;;;;;42689:26:0;;::::1;;::::0;;;:17:::1;:26;::::0;;;;;;;;:58;;-1:-1:-1;;;;;;42689:58:0::1;::::0;;::::1;::::0;;::::1;::::0;;42765:40;;2656:51:1;;;42689:26:0;;42765:40:::1;::::0;2629:18:1;42765:40:0::1;2611:102:1::0;42256:140:0;9175:15;:13;:15::i;:::-;40417:13:::1;::::0;::::1;;40416:14;40408:56;;;;-1:-1:-1::0;;;40408:56:0::1;;;;;;;:::i;:::-;42335:13:::2;:20:::0;;-1:-1:-1;;42335:20:0::2;42351:4;42335:20;::::0;;42373:15:::2;::::0;::::2;::::0;42335:13:::2;::::0;42373:15:::2;42256:140::o:0;24352:622::-;24722:10;;;24721:62;;-1:-1:-1;24738:39:0;;-1:-1:-1;;;24738:39:0;;24762:4;24738:39;;;2930:34:1;-1:-1:-1;;;;;3000:15:1;;;2980:18;;;2973:43;24738:15:0;;;;;2865:18:1;;24738:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;24721:62;24713:152;;;;-1:-1:-1;;;24713:152:0;;12686:2:1;24713:152:0;;;12668:21:1;12725:2;12705:18;;;12698:30;12764:34;12744:18;;;12737:62;-1:-1:-1;;;12815:18:1;;;12808:52;12877:19;;24713:152:0;12658:244:1;24713:152:0;24903:62;;-1:-1:-1;;;;;3599:32:1;;24903:62:0;;;3581:51:1;3648:18;;;3641:34;;;24876:90:0;;24896:5;;-1:-1:-1;;;24926:22:0;3554:18:1;;24903:62:0;;;;-1:-1:-1;;24903:62:0;;;;;;;;;;;;;;-1:-1:-1;;;;;24903:62:0;-1:-1:-1;;;;;;24903:62:0;;;;;;;;;;24876:19;:90::i;:::-;24352:622;;;:::o;19293:195::-;19396:12;19428:52;19450:6;19458:4;19464:1;19467:12;19428:21;:52::i;:::-;19421:59;;19293:195;;;;;;:::o;46293:521::-;-1:-1:-1;;;;;46463:23:0;;46408:16;46463:23;;;:14;:23;;;;;;46408:16;;46535:7;:32;;;;;;-1:-1:-1;;;46535:32:0;;;;;;;;;;:76;;-1:-1:-1;;;;;46591:20:0;;;;;;:11;:20;;;;;46535:76;;;-1:-1:-1;;;;;46570:18:0;;;;;;:9;:18;;;;;46535:76;46499:112;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;46665:23:0;;46661:98;;;46724:10;;:23;;46737:10;;46724:23;:::i;:::-;46705:42;;46661:98;46795:11;;;;46776:30;;:16;:30;:::i;:::-;46769:37;46293:521;-1:-1:-1;;;;;;46293:521:0:o;9218:121::-;9290:11;:9;:11::i;:::-;-1:-1:-1;;;;;9276:25:0;:10;-1:-1:-1;;;;;9276:25:0;;9268:63;;;;-1:-1:-1;;;9268:63:0;;8316:2:1;9268:63:0;;;8298:21:1;8355:2;8335:18;;;8328:30;8394:27;8374:18;;;8367:55;8439:18;;9268:63:0;8288:175:1;9268:63:0;9218:121::o;41767:421::-;-1:-1:-1;;;;;41870:21:0;;;;;;:55;;-1:-1:-1;;;;;;41895:30:0;;;;41870:55;41862:89;;;;-1:-1:-1;;;41862:89:0;;11925:2:1;41862:89:0;;;11907:21:1;11964:2;11944:18;;;11937:30;-1:-1:-1;;;11983:18:1;;;11976:51;12044:18;;41862:89:0;11897:171:1;41862:89:0;-1:-1:-1;;;;;41962:25:0;;;;;;;:16;:25;;;;;:64;;-1:-1:-1;;;;;;41962:64:0;;;;;;;;;;;42039:57;;41962:64;;42039:27;:57::i;:::-;42107:73;-1:-1:-1;;;;;42107:27:0;;42143:16;-1:-1:-1;;42107:27:0;:73::i;:::-;41767:421;;:::o;10906:112::-;10979:31;;-1:-1:-1;;;10979:31:0;;7853:66;10979:31;;;4024:25:1;10952:7:0;;10979:5;-1:-1:-1;;;;;10979:15:0;;;;3997:18:1;;10979:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10972:38;;10906:112;:::o;48342:2966::-;-1:-1:-1;;;;;48455:25:0;;;48418:34;48455:25;;;:16;:25;;;;;;;48499:38;48491:85;;;;-1:-1:-1;;;48491:85:0;;7506:2:1;48491:85:0;;;7488:21:1;7545:2;7525:18;;;7518:30;7584:34;7564:18;;;7557:62;-1:-1:-1;;;7635:18:1;;;7628:32;7677:19;;48491:85:0;7478:224:1;48491:85:0;-1:-1:-1;;;;;48652:24:0;;48624:25;48652:24;;;:15;:24;;;;;;;;;48716:14;:23;;;;;;;;;48776:15;48750:41;;;48955:24;;-1:-1:-1;;;48955:24:0;;;;48652;;48716:23;;48668:7;;48624:25;;;;48955:22;;:24;;;;;;;;;;48624:25;48652:24;48955;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48904:75;;-1:-1:-1;48904:75:0;-1:-1:-1;49114:28:0;49145:54;49160:1;49163:35;49181:17;49163:15;:35;:::i;:::-;49145:14;:54::i;:::-;49114:85;-1:-1:-1;49210:31:0;49244:55;49259:1;49262:36;49280:18;49262:15;:36;:::i;49244:55::-;49210:89;-1:-1:-1;49339:17:0;39386:10;49450:40;;49446:631;;;-1:-1:-1;;;;;49507:24:0;;;;;;:15;:24;;;;;;;;49534:15;49507:42;;49564:11;:20;;;;;:24;49446:631;;;39386:10;49710:20;:37;49706:371;;;-1:-1:-1;;;;;49764:24:0;;;;;;:15;:24;;;;;;;;:45;;;49824:11;:20;;;;;:40;;;49706:371;;;-1:-1:-1;;;;;49971:20:0;;;;;;:11;:20;;;;;;:40;;49994:17;;49971:40;:::i;:::-;-1:-1:-1;;;;;50026:20:0;;;;;;:11;:20;;;;;:39;;;49952:59;-1:-1:-1;49706:371:0;50122:17;50142:46;50160:7;50169:18;50142:17;:46::i;:::-;50122:66;;50312:1;50292:17;:21;:38;;;;50329:1;50317:9;:13;50292:38;50288:1013;;;50417:29;50437:9;50417:17;:29;:::i;:::-;50373:40;;-1:-1:-1;;;50373:40:0;;50407:4;50373:40;;;2656:51:1;-1:-1:-1;;;;;50373:25:0;;;;;2629:18:1;;50373:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:73;;50347:152;;;;-1:-1:-1;;;50347:152:0;;6386:2:1;50347:152:0;;;6368:21:1;6425:2;6405:18;;;6398:30;-1:-1:-1;;;6444:18:1;;;6437:47;6501:18;;50347:152:0;6358:167:1;50347:152:0;50516:23;50559:171;50615:11;50649:16;50688:23;50559:33;:171::i;:::-;50752:75;;;4967:25:1;;;5023:2;5008:18;;5001:34;;;5051:18;;;5044:34;;;50516:214:0;;-1:-1:-1;;;;;;50752:75:0;;;-1:-1:-1;;;;;;;;;;;50752:75:0;4955:2:1;4940:18;50752:75:0;;;;;;;50952:19;50974:56;51018:11;;50995:9;50975:17;:29;;;;:::i;:::-;50974:43;;:56::i;:::-;51099:44;;-1:-1:-1;;;51099:44:0;;;;;4024:25:1;;;50952:78:0;;-1:-1:-1;;;;;;51099:31:0;;;;;3997:18:1;;51099:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51185:7;-1:-1:-1;;;;;51165:41:0;;51194:11;51165:41;;;;4024:25:1;;4012:2;3997:18;;3979:76;51165:41:0;;;;;;;;50288:1013;;;;;51244:45;;;51271:1;4967:25:1;;;5023:2;5008:18;;5001:34;;;5051:18;;;5044:34;51244:45:0;;-1:-1:-1;;;;;51244:45:0;;;-1:-1:-1;;;;;;;;;;;51244:45:0;;;;;4955:2:1;51244:45:0;;;50288:1013;48342:2966;;;;;;;;;;;:::o;23878:205::-;24006:68;;-1:-1:-1;;;;;3285:15:1;;;24006:68:0;;;3267:34:1;3337:15;;3317:18;;;3310:43;3369:18;;;3362:34;;;23979:96:0;;23999:5;;-1:-1:-1;;;24029:27:0;3202:18:1;;24006:68:0;3184:218:1;23979:96:0;23878:205;;;;:::o;47032:702::-;47217:15;47195:19;47314;47324:9;47314:7;:19;:::i;:::-;47299:34;-1:-1:-1;47344:11:0;47358:23;47372:9;47358:11;:23;:::i;:::-;47344:37;-1:-1:-1;47407:21:0;47396:7;:32;;;;;;-1:-1:-1;;;47396:32:0;;;;;;;;;;47392:176;;;47466:17;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;47445:18:0;;-1:-1:-1;47445:18:0;;;:9;:18;;;;;;:38;;;;;;;;;;;47392:176;;;47539:17;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;47516:20:0;;-1:-1:-1;47516:20:0;;;:11;:20;;;;;;:40;;;;;;;;;;;47392:176;-1:-1:-1;;;;;47653:23:0;;;;;;:14;:23;;;;;;:38;;47645:81;;;;-1:-1:-1;;;47645:81:0;;11208:2:1;47645:81:0;;;11190:21:1;11247:2;11227:18;;;11220:30;11286:32;11266:18;;;11259:60;11336:18;;47645:81:0;11180:180:1;47645:81:0;47032:702;;;;;;;:::o;34929:307::-;35087:23;35143:85;35162:10;35174:9;35185:24;34453:5;34500:4;35143:18;:85::i;26127:761::-;26551:23;26577:69;26605:4;26577:69;;;;;;;;;;;;;;;;;26585:5;-1:-1:-1;;;;;26577:27:0;;;:69;;;;;:::i;:::-;26661:17;;26551:95;;-1:-1:-1;26661:21:0;26657:224;;26803:10;26792:30;;;;;;;;;;;;:::i;:::-;26784:85;;;;-1:-1:-1;;;26784:85:0;;12275:2:1;26784:85:0;;;12257:21:1;12314:2;12294:18;;;12287:30;12353:34;12333:18;;;12326:62;-1:-1:-1;;;12404:18:1;;;12397:40;12454:19;;26784:85:0;12247:232:1;20345:530:0;20472:12;20530:5;20505:21;:30;;20497:81;;;;-1:-1:-1;;;20497:81:0;;7909:2:1;20497:81:0;;;7891:21:1;7948:2;7928:18;;;7921:30;7987:34;7967:18;;;7960:62;-1:-1:-1;;;8038:18:1;;;8031:36;8084:19;;20497:81:0;7881:228:1;20497:81:0;16742:20;;20589:60;;;;-1:-1:-1;;;20589:60:0;;11567:2:1;20589:60:0;;;11549:21:1;11606:2;11586:18;;;11579:30;11645:31;11625:18;;;11618:59;11694:18;;20589:60:0;11539:179:1;20589:60:0;20723:12;20737:23;20764:6;-1:-1:-1;;;;;20764:11:0;20784:5;20792:4;20764:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20722:75;;;;20815:52;20833:7;20842:10;20854:12;20815:17;:52::i;:::-;20808:59;20345:530;-1:-1:-1;;;;;;;20345:530:0:o;9825:95::-;9869:7;9896:5;-1:-1:-1;;;;;9896:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33772:106;33830:7;33861:1;33857;:5;:13;;33869:1;33857:13;;;-1:-1:-1;33865:1:0;;33850:20;-1:-1:-1;33772:106:0:o;51574:616::-;-1:-1:-1;;;;;51742:18:0;;51697:7;51742:18;;;:9;:18;;;;;;;;51722:38;;;;;;;;;;;;;;;;;;;;;;;;;;51697:7;;51802:47;;51820:19;;51802:17;:47::i;:::-;51771:78;;51860:20;51906:3;:8;;;51883:20;:31;;;;:::i;:::-;-1:-1:-1;;;;;51949:20:0;;51927:19;51949:20;;;:11;:20;;;;;;;;51927:42;;;;;;;;;;;;;;;;;;;;;;;;;51860:54;;-1:-1:-1;52013:49:0;;52031:19;;52013:17;:49::i;:::-;51980:82;;52073:22;52123:5;:10;;;52098:22;:35;;;;:::i;:::-;52073:60;-1:-1:-1;52153:29:0;52073:60;52153:12;:29;:::i;:::-;52146:36;51574:616;-1:-1:-1;;;;;;;;;51574:616:0:o;28719:135::-;28785:7;28812:34;28829:1;28832;27093:4;28812:16;:34::i;35819:1549::-;36030:23;;36090:29;;:60;;36126:24;36090:60;;;36122:1;36090:60;36066:84;-1:-1:-1;36375:17:0;36395:22;36408:9;36395:10;:22;:::i;:::-;36375:42;-1:-1:-1;36428:26:0;36375:42;36458:16;:9;36470:4;36458:16;:::i;:::-;36457:30;;;;:::i;:::-;36428:59;-1:-1:-1;36736:32:0;34342:8;36772:20;:13;36788:4;36772:20;:::i;:::-;36771:40;;;;:::i;:::-;36736:75;-1:-1:-1;36736:75:0;37029:25;:18;37050:4;37029:25;:::i;:::-;37028:54;;;;:::i;:::-;37010:72;;34399:10;37099:13;:30;37095:266;;;37172:7;37154:15;:25;37146:83;;;;-1:-1:-1;;;37146:83:0;;10794:2:1;37146:83:0;;;10776:21:1;10833:2;10813:18;;;10806:30;10872:34;10852:18;;;10845:62;-1:-1:-1;;;10923:18:1;;;10916:43;10976:19;;37146:83:0;10766:235:1;37146:83:0;37095:266;;;37291:8;37270:18;:29;37262:87;;;;-1:-1:-1;;;37262:87:0;;7092:2:1;37262:87:0;;;7074:21:1;7131:2;7111:18;;;7104:30;7170:34;7150:18;;;7143:62;-1:-1:-1;;;7221:18:1;;;7214:43;7274:19;;37262:87:0;7064:235:1;37262:87:0;35819:1549;;;;;;;;;;;:::o;22885:742::-;23000:12;23029:7;23025:595;;;-1:-1:-1;23060:10:0;23053:17;;23025:595;23174:17;;:21;23170:439;;23437:10;23431:17;23498:15;23485:10;23481:2;23477:19;23470:44;23385:148;23580:12;23573:20;;-1:-1:-1;;;23573:20:0;;;;;;;;:::i;52444:425::-;52529:7;52571:15;52529:7;52642:19;;;52638:190;;52697:25;52711:11;52697;:25;:::i;:::-;52678:44;;52638:190;;;52758:4;52744:11;:18;52740:88;;;52798:18;52805:11;52798:4;:18;:::i;:::-;52779:37;;52740:88;52845:16;52444:425;-1:-1:-1;;;;52444:425:0:o;29327:286::-;29447:7;29600:5;29591;29595:1;29591;:5;:::i;:::-;29590:15;;;;:::i;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;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:398::-;;;671:2;659:9;650:7;646:23;642:32;639:2;;;692:6;684;677:22;639:2;736:9;723:23;755:31;780:5;755:31;:::i;:::-;805:5;-1:-1:-1;862:2:1;847:18;;834:32;875:33;834:32;875:33;:::i;:::-;927:7;917:17;;;629:311;;;;;:::o;945:325::-;;;1074:2;1062:9;1053:7;1049:23;1045:32;1042:2;;;1095:6;1087;1080:22;1042:2;1139:9;1126:23;1158:31;1183:5;1158:31;:::i;:::-;1208:5;1260:2;1245:18;;;;1232:32;;-1:-1:-1;;;1032:238:1:o;1275:297::-;;1395:2;1383:9;1374:7;1370:23;1366:32;1363:2;;;1416:6;1408;1401:22;1363:2;1453:9;1447:16;1506:5;1499:13;1492:21;1485:5;1482:32;1472:2;;1533:6;1525;1518:22;1577:190;;1689:2;1677:9;1668:7;1664:23;1660:32;1657:2;;;1710:6;1702;1695:22;1657:2;-1:-1:-1;1738:23:1;;1647:120;-1:-1:-1;1647:120:1:o;1772:194::-;;1895:2;1883:9;1874:7;1870:23;1866:32;1863:2;;;1916:6;1908;1901:22;1863:2;-1:-1:-1;1944:16:1;;1853:113;-1:-1:-1;1853:113:1:o;1971:255::-;;;2111:2;2099:9;2090:7;2086:23;2082:32;2079:2;;;2132:6;2124;2117:22;2079:2;-1:-1:-1;;2160:16:1;;2216:2;2201:18;;;2195:25;2160:16;;2195:25;;-1:-1:-1;2069:157:1:o;2231:274::-;;2398:6;2392:13;2414:53;2460:6;2455:3;2448:4;2440:6;2436:17;2414:53;:::i;:::-;2483:16;;;;;2368:137;-1:-1:-1;;2368:137:1:o;5089:383::-;;5238:2;5227:9;5220:21;5270:6;5264:13;5313:6;5308:2;5297:9;5293:18;5286:34;5329:66;5388:6;5383:2;5372:9;5368:18;5363:2;5355:6;5351:15;5329:66;:::i;:::-;5456:2;5435:15;-1:-1:-1;;5431:29:1;5416:45;;;;5463:2;5412:54;;5210:262;-1:-1:-1;;5210:262:1:o;5477:353::-;5679:2;5661:21;;;5718:2;5698:18;;;5691:30;5757:31;5752:2;5737:18;;5730:59;5821:2;5806:18;;5651:179::o;8468:340::-;8670:2;8652:21;;;8709:2;8689:18;;;8682:30;-1:-1:-1;;;8743:2:1;8728:18;;8721:46;8799:2;8784:18;;8642:166::o;13998:128::-;;14069:1;14065:6;14062:1;14059:13;14056:2;;;14075:18;;:::i;:::-;-1:-1:-1;14111:9:1;;14046:80::o;14131:217::-;;14197:1;14187:2;;-1:-1:-1;;;14222:31:1;;14276:4;14273:1;14266:15;14304:4;14229:1;14294:15;14187:2;-1:-1:-1;14333:9:1;;14177:171::o;14353:168::-;;14459:1;14455;14451:6;14447:14;14444:1;14441:21;14436:1;14429:9;14422:17;14418:45;14415:2;;;14466:18;;:::i;:::-;-1:-1:-1;14506:9:1;;14405:116::o;14526:125::-;;14594:1;14591;14588:8;14585:2;;;14599:18;;:::i;:::-;-1:-1:-1;14636:9:1;;14575:76::o;14656:258::-;14728:1;14738:113;14752:6;14749:1;14746:13;14738:113;;;14828:11;;;14822:18;14809:11;;;14802:39;14774:2;14767:10;14738:113;;;14869:6;14866:1;14863:13;14860:2;;;-1:-1:-1;;14904:1:1;14886:16;;14879:27;14709:205::o;14919:127::-;14980:10;14975:3;14971:20;14968:1;14961:31;15011:4;15008:1;15001:15;15035:4;15032:1;15025:15;15051:131;-1:-1:-1;;;;;15126:31:1;;15116:42;;15106:2;;15172:1;15169;15162:12
Swarm Source
ipfs://83e7f1d2b8388b7a75e9e2e56270159639d5940256eb6f0ae499255ad51e29cb
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.