Latest 25 from a total of 9,777 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Redeem | 15376457 | 1283 days ago | IN | 0 ETH | 0.0005554 | ||||
| Redeem | 15263588 | 1301 days ago | IN | 0 ETH | 0.00105573 | ||||
| Redeem | 13776911 | 1536 days ago | IN | 0 ETH | 0.00323663 | ||||
| Redeem | 13532310 | 1575 days ago | IN | 0 ETH | 0.01682071 | ||||
| Redeem | 13469285 | 1585 days ago | IN | 0 ETH | 0.00689448 | ||||
| Redeem | 13436246 | 1590 days ago | IN | 0 ETH | 0.00571269 | ||||
| Redeem | 13337509 | 1605 days ago | IN | 0 ETH | 0.00468123 | ||||
| Redeem | 13270510 | 1616 days ago | IN | 0 ETH | 0.01261553 | ||||
| Redeem | 13264880 | 1616 days ago | IN | 0 ETH | 0.00380846 | ||||
| Redeem | 13006356 | 1656 days ago | IN | 0 ETH | 0.00460189 | ||||
| Redeem | 12888123 | 1675 days ago | IN | 0 ETH | 0.00076057 | ||||
| Redeem | 12868816 | 1678 days ago | IN | 0 ETH | 0.00103696 | ||||
| Redeem | 12780770 | 1692 days ago | IN | 0 ETH | 0.00269657 | ||||
| Redeem | 12674821 | 1708 days ago | IN | 0 ETH | 0.00034571 | ||||
| Redeem | 12662140 | 1710 days ago | IN | 0 ETH | 0.000484 | ||||
| Redeem | 12642329 | 1713 days ago | IN | 0 ETH | 0.00048391 | ||||
| Redeem | 12635115 | 1714 days ago | IN | 0 ETH | 0.00038227 | ||||
| Redeem | 12635115 | 1714 days ago | IN | 0 ETH | 0.00091268 | ||||
| Redeem | 12627058 | 1716 days ago | IN | 0 ETH | 0.00062228 | ||||
| Redeem | 12586158 | 1722 days ago | IN | 0 ETH | 0.00082971 | ||||
| Redeem | 12582227 | 1723 days ago | IN | 0 ETH | 0.00165943 | ||||
| Redeem | 12578640 | 1723 days ago | IN | 0 ETH | 0.00069212 | ||||
| Redeem | 12570540 | 1724 days ago | IN | 0 ETH | 0.00124903 | ||||
| Redeem | 12528103 | 1731 days ago | IN | 0 ETH | 0.00138286 | ||||
| Redeem | 12519951 | 1732 days ago | IN | 0 ETH | 0.00158309 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
SavingsContract
Compiler Version
v0.5.16+commit.9c3226ce
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion, GNU GPLv3 license, Audited
Contract Source Code (Solidity)Audit Report
/**
*Submitted for verification at Etherscan.io on 2020-05-28
*/
pragma solidity 0.5.16;
interface ISavingsManager {
/** @dev Admin privs */
function withdrawUnallocatedInterest(address _mAsset, address _recipient) external;
/** @dev Public privs */
function collectAndDistributeInterest(address _mAsset) external;
}
interface ISavingsContract {
/** @dev Manager privs */
function depositInterest(uint256 _amount) external;
/** @dev Saver privs */
function depositSavings(uint256 _amount) external returns (uint256 creditsIssued);
function redeem(uint256 _amount) external returns (uint256 massetReturned);
}
/**
* @title ModuleKeys
* @author Stability Labs Pty. Ltd.
* @notice Provides system wide access to the byte32 represntations of system modules
* This allows each system module to be able to reference and update one another in a
* friendly way
* @dev keccak256() values are hardcoded to avoid re-evaluation of the constants at runtime.
*/
contract ModuleKeys {
// 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;
// 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;
}
/**
* @title INexus
* @dev Basic interface for interacting with the Nexus i.e. SystemKernel
*/
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;
}
/**
* @title Module
* @author Stability Labs Pty. Ltd.
* @dev Subscribes to module updates from a given publisher by reading from its registry
*/
contract Module is ModuleKeys {
INexus public nexus;
/**
* @dev Initialises the Module by setting publisher addresses,
* and reading all available system module information
*/
constructor(address _nexus) internal {
require(_nexus != address(0), "Nexus is zero address");
nexus = INexus(_nexus);
}
/**
* @dev Modifier to allow function calls only from the Governor.
*/
modifier onlyGovernor() {
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 Modifier to allow function calls only from the ProxyAdmin.
*/
modifier onlyProxyAdmin() {
require(
msg.sender == _proxyAdmin(), "Only ProxyAdmin can execute"
);
_;
}
/**
* @dev Modifier to allow function calls only from the Manager.
*/
modifier onlyManager() {
require(msg.sender == _manager(), "Only manager 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 Staking Module address from the Nexus
* @return Address of the Staking Module contract
*/
function _staking() internal view returns (address) {
return nexus.getModule(KEY_STAKING);
}
/**
* @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);
}
/**
* @dev Return MetaToken Module address from the Nexus
* @return Address of the MetaToken Module contract
*/
function _metaToken() internal view returns (address) {
return nexus.getModule(KEY_META_TOKEN);
}
/**
* @dev Return OracleHub Module address from the Nexus
* @return Address of the OracleHub Module contract
*/
function _oracleHub() internal view returns (address) {
return nexus.getModule(KEY_ORACLE_HUB);
}
/**
* @dev Return Manager Module address from the Nexus
* @return Address of the Manager Module contract
*/
function _manager() internal view returns (address) {
return nexus.getModule(KEY_MANAGER);
}
/**
* @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);
}
}
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 Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*
* _Available since v2.4.0._
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
/**
* @title StableMath
* @author Stability Labs Pty. Ltd.
* @notice A library providing safe mathematical operations to multiply and
* divide with standardised precision.
* @dev Derives from OpenZeppelin's SafeMath lib and uses generic system
* wide variables for managing precision.
*/
library StableMath {
using SafeMath for uint256;
/**
* @dev Scaling unit for use in specific calculations,
* where 1 * 10**18, or 1e18 represents a unit '1'
*/
uint256 private constant FULL_SCALE = 1e18;
/**
* @notice 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)
* @dev 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.mul(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)
{
uint256 z = x.mul(y);
return z.div(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)
{
uint256 scaled = x.mul(y);
uint256 ceil = scaled.add(FULL_SCALE.sub(1));
return ceil.div(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)
{
uint256 z = x.mul(FULL_SCALE);
return z.div(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 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)
{
uint256 scaled = x.mul(ratio);
uint256 ceil = scaled.add(RATIO_SCALE.sub(1));
return ceil.div(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 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)
{
uint256 y = x.mul(RATIO_SCALE);
return y.div(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;
}
}
/**
* @title SavingsContract
* @author Stability Labs Pty. Ltd.
* @notice Savings contract uses the ever increasing "exchangeRate" to increase
* the value of the Savers "credits" relative to the amount of additional
* underlying collateral that has been deposited into this contract ("interest")
* @dev VERSION: 1.0
* DATE: 2020-03-28
*/
contract SavingsContract is ISavingsContract, Module {
using SafeMath for uint256;
using StableMath for uint256;
// Core events for depositing and withdrawing
event ExchangeRateUpdated(uint256 newExchangeRate, uint256 interestCollected);
event SavingsDeposited(address indexed saver, uint256 savingsDeposited, uint256 creditsIssued);
event CreditsRedeemed(address indexed redeemer, uint256 creditsRedeemed, uint256 savingsCredited);
event AutomaticInterestCollectionSwitched(bool automationEnabled);
// Underlying asset is mUSD
IERC20 private mUSD;
// Amount of underlying savings in the contract
uint256 public totalSavings;
// Total number of savings credits issued
uint256 public totalCredits;
// Rate between 'savings credits' and mUSD
// e.g. 1 credit (1e18) mulTruncate(exchangeRate) = mUSD, starts at 1:1
// exchangeRate increases over time and is essentially a percentage based value
uint256 public exchangeRate = 1e18;
// Amount of credits for each saver
mapping(address => uint256) public creditBalances;
bool private automateInterestCollection = true;
constructor(address _nexus, IERC20 _mUSD)
public
Module(_nexus)
{
require(address(_mUSD) != address(0), "mAsset address is zero");
mUSD = _mUSD;
}
/** @dev Only the savings managaer (pulled from Nexus) can execute this */
modifier onlySavingsManager() {
require(msg.sender == _savingsManager(), "Only savings manager can execute");
_;
}
/** @dev Enable or disable the automation of fee collection during deposit process */
function automateInterestCollectionFlag(bool _enabled)
external
onlyGovernor
{
automateInterestCollection = _enabled;
emit AutomaticInterestCollectionSwitched(_enabled);
}
/***************************************
INTEREST
****************************************/
/**
* @dev Deposit interest (add to savings) and update exchange rate of contract.
* Exchange rate is calculated as the ratio between new savings q and credits:
* exchange rate = savings / credits
*
* @param _amount Units of underlying to add to the savings vault
*/
function depositInterest(uint256 _amount)
external
onlySavingsManager
{
require(_amount > 0, "Must deposit something");
// Transfer the interest from sender to here
require(mUSD.transferFrom(msg.sender, address(this), _amount), "Must receive tokens");
totalSavings = totalSavings.add(_amount);
// Calc new exchange rate, protect against initialisation case
if(totalCredits > 0) {
// new exchange rate is relationship between totalCredits & totalSavings
// exchangeRate = totalSavings/totalCredits
exchangeRate = totalSavings.divPrecisely(totalCredits);
emit ExchangeRateUpdated(exchangeRate, _amount);
}
}
/***************************************
SAVING
****************************************/
/**
* @dev Deposit the senders savings to the vault, and credit them internally with "credits".
* Credit amount is calculated as a ratio of deposit amount and exchange rate:
* credits = underlying / exchangeRate
* If automation is enabled, we will first update the internal exchange rate by
* collecting any interest generated on the underlying.
* @param _amount Units of underlying to deposit into savings vault
* @return creditsIssued Units of credits issued internally
*/
function depositSavings(uint256 _amount)
external
returns (uint256 creditsIssued)
{
require(_amount > 0, "Must deposit something");
if(automateInterestCollection) {
// Collect recent interest generated by basket and update exchange rate
ISavingsManager(_savingsManager()).collectAndDistributeInterest(address(mUSD));
}
// Transfer tokens from sender to here
require(mUSD.transferFrom(msg.sender, address(this), _amount), "Must receive tokens");
totalSavings = totalSavings.add(_amount);
// Calc how many credits they receive based on currentRatio
creditsIssued = _massetToCredit(_amount);
totalCredits = totalCredits.add(creditsIssued);
// add credits to balances
creditBalances[msg.sender] = creditBalances[msg.sender].add(creditsIssued);
emit SavingsDeposited(msg.sender, _amount, creditsIssued);
}
/**
* @dev Redeem specific number of the senders "credits" in exchange for underlying.
* Payout amount is calculated as a ratio of credits and exchange rate:
* payout = credits * exchangeRate
* @param _credits Amount of credits to redeem
* @return massetReturned Units of underlying mAsset paid out
*/
function redeem(uint256 _credits)
external
returns (uint256 massetReturned)
{
require(_credits > 0, "Must withdraw something");
uint256 saverCredits = creditBalances[msg.sender];
require(saverCredits >= _credits, "Saver has no credits");
creditBalances[msg.sender] = saverCredits.sub(_credits);
totalCredits = totalCredits.sub(_credits);
// Calc payout based on currentRatio
massetReturned = _creditToMasset(_credits);
totalSavings = totalSavings.sub(massetReturned);
// Transfer tokens from here to sender
require(mUSD.transfer(msg.sender, massetReturned), "Must send tokens");
emit CreditsRedeemed(msg.sender, _credits, massetReturned);
}
/**
* @dev Converts masset amount into credits based on exchange rate
* c = masset / exchangeRate
*/
function _massetToCredit(uint256 _amount)
internal
view
returns (uint256 credits)
{
credits = _amount.divPrecisely(exchangeRate);
}
/**
* @dev Converts masset amount into credits based on exchange rate
* m = credits * exchangeRate
*/
function _creditToMasset(uint256 _credits)
internal
view
returns (uint256 massetAmount)
{
massetAmount = _credits.mulTruncate(exchangeRate);
}
}Contract Security Audit
- Consensys Diligence - August 10th, 2020 - Security Audit Report
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_nexus","type":"address"},{"internalType":"contract IERC20","name":"_mUSD","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"automationEnabled","type":"bool"}],"name":"AutomaticInterestCollectionSwitched","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"redeemer","type":"address"},{"indexed":false,"internalType":"uint256","name":"creditsRedeemed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"savingsCredited","type":"uint256"}],"name":"CreditsRedeemed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newExchangeRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"interestCollected","type":"uint256"}],"name":"ExchangeRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"saver","type":"address"},{"indexed":false,"internalType":"uint256","name":"savingsDeposited","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"creditsIssued","type":"uint256"}],"name":"SavingsDeposited","type":"event"},{"constant":false,"inputs":[{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"automateInterestCollectionFlag","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"creditBalances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositInterest","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositSavings","outputs":[{"internalType":"uint256","name":"creditsIssued","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"exchangeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"nexus","outputs":[{"internalType":"contract INexus","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_credits","type":"uint256"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"massetReturned","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalCredits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSavings","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]Contract Creation Code
6080604052670de0b6b3a76400006004556006805460ff1916600117905534801561002957600080fd5b50604051610e30380380610e308339818101604052604081101561004c57600080fd5b508051602090910151816001600160a01b0381166100b1576040805162461bcd60e51b815260206004820152601560248201527f4e65787573206973207a65726f20616464726573730000000000000000000000604482015290519081900360640190fd5b600080546001600160a01b0319166001600160a01b039283161790558116610120576040805162461bcd60e51b815260206004820152601660248201527f6d41737365742061646472657373206973207a65726f00000000000000000000604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b039290921691909117905550610ce0806101506000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c8063a3f5c1d211610066578063a3f5c1d2146100ff578063a453b6cf14610123578063b5bd3eb914610140578063cbe5417314610148578063db006a751461016757610093565b8063220c5bbb146100985780633ba0b9a9146100b75780636009a2d8146100d15780639bf42b3f146100f7575b600080fd5b6100b5600480360360208110156100ae57600080fd5b5035610184565b005b6100bf610382565b60408051918252519081900360200190f35b6100bf600480360360208110156100e757600080fd5b50356001600160a01b0316610388565b6100bf61039a565b6101076103a0565b604080516001600160a01b039092168252519081900360200190f35b6100bf6004803603602081101561013957600080fd5b50356103af565b6100bf6105f4565b6100b56004803603602081101561015e57600080fd5b503515156105fa565b6100bf6004803603602081101561017d57600080fd5b50356106ae565b61018c6108bc565b6001600160a01b0316336001600160a01b0316146101f1576040805162461bcd60e51b815260206004820181905260248201527f4f6e6c7920736176696e6773206d616e616765722063616e2065786563757465604482015290519081900360640190fd5b6000811161023f576040805162461bcd60e51b81526020600482015260166024820152754d757374206465706f73697420736f6d657468696e6760501b604482015290519081900360640190fd5b600154604080516323b872dd60e01b81523360048201523060248201526044810184905290516001600160a01b03909216916323b872dd916064808201926020929091908290030181600087803b15801561029957600080fd5b505af11580156102ad573d6000803e3d6000fd5b505050506040513d60208110156102c357600080fd5b505161030c576040805162461bcd60e51b81526020600482015260136024820152724d757374207265636569766520746f6b656e7360681b604482015290519081900360640190fd5b60025461031f908263ffffffff61095916565b6002556003541561037f5760035460025461033f9163ffffffff6109bc16565b6004819055604080519182526020820183905280517fc8d1043f24843c0a1c9251fdc30017d84e87498fbcf232af9f86816b5e182bde9281900390910190a15b50565b60045481565b60056020526000908152604090205481565b60025481565b6000546001600160a01b031681565b60008082116103fe576040805162461bcd60e51b81526020600482015260166024820152754d757374206465706f73697420736f6d657468696e6760501b604482015290519081900360640190fd5b60065460ff1615610479576104116108bc565b60015460408051636515eff360e11b81526001600160a01b0392831660048201529051929091169163ca2bdfe69160248082019260009290919082900301818387803b15801561046057600080fd5b505af1158015610474573d6000803e3d6000fd5b505050505b600154604080516323b872dd60e01b81523360048201523060248201526044810185905290516001600160a01b03909216916323b872dd916064808201926020929091908290030181600087803b1580156104d357600080fd5b505af11580156104e7573d6000803e3d6000fd5b505050506040513d60208110156104fd57600080fd5b5051610546576040805162461bcd60e51b81526020600482015260136024820152724d757374207265636569766520746f6b656e7360681b604482015290519081900360640190fd5b600254610559908363ffffffff61095916565b600255610565826109f1565b60035490915061057b908263ffffffff61095916565b6003553360009081526005602052604090205461059e908263ffffffff61095916565b33600081815260056020908152604091829020939093558051858152928301849052805191927f1a96ef469e332471886959f90a71ae924792a05ad7eea4e43a1c29becdf238ed929081900390910190a2919050565b60035481565b610602610a08565b6001600160a01b0316336001600160a01b031614610667576040805162461bcd60e51b815260206004820152601960248201527f4f6e6c7920676f7665726e6f722063616e206578656375746500000000000000604482015290519081900360640190fd5b6006805482151560ff19909116811790915560408051918252517fb9fdedbd8818c7929701eadc08c748a262fb39d9237b27537ae1809061e305f69181900360200190a150565b6000808211610704576040805162461bcd60e51b815260206004820152601760248201527f4d75737420776974686472617720736f6d657468696e67000000000000000000604482015290519081900360640190fd5b3360009081526005602052604090205482811015610760576040805162461bcd60e51b8152602060048201526014602482015273536176657220686173206e6f206372656469747360601b604482015290519081900360640190fd5b610770818463ffffffff610a5716565b33600090815260056020526040902055600354610793908463ffffffff610a5716565b60035561079f83610a99565b6002549092506107b5908363ffffffff610a5716565b6002556001546040805163a9059cbb60e01b81523360048201526024810185905290516001600160a01b039092169163a9059cbb916044808201926020929091908290030181600087803b15801561080c57600080fd5b505af1158015610820573d6000803e3d6000fd5b505050506040513d602081101561083657600080fd5b505161087c576040805162461bcd60e51b815260206004820152601060248201526f4d7573742073656e6420746f6b656e7360801b604482015290519081900360640190fd5b6040805184815260208101849052815133927fa4feb388d266c39bec6f79f16c3a7dba32e12d9688ddbb14493d46ce4c1ce657928290030190a250919050565b60008054604080516385acd64160e01b81527f12fe936c77a1e196473c4314f3bed8eeac1d757b319abb85bdda70df35511bf1600482015290516001600160a01b03909216916385acd64191602480820192602092909190829003018186803b15801561092857600080fd5b505afa15801561093c573d6000803e3d6000fd5b505050506040513d602081101561095257600080fd5b5051905090565b6000828201838110156109b3576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b6000806109d784670de0b6b3a764000063ffffffff610ab016565b90506109e9818463ffffffff610b0916565b949350505050565b60006109b6600454836109bc90919063ffffffff16565b60008060009054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b15801561092857600080fd5b60006109b383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610b4b565b60006109b660045483610be290919063ffffffff16565b600082610abf575060006109b6565b82820282848281610acc57fe5b04146109b35760405162461bcd60e51b8152600401808060200182810382526021815260200180610c8b6021913960400191505060405180910390fd5b60006109b383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610bf7565b60008184841115610bda5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610b9f578181015183820152602001610b87565b50505050905090810190601f168015610bcc5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60006109b38383670de0b6b3a7640000610c5c565b60008183610c465760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b9f578181015183820152602001610b87565b506000838581610c5257fe5b0495945050505050565b600080610c6f858563ffffffff610ab016565b9050610c81818463ffffffff610b0916565b9594505050505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a265627a7a72315820b5f2ac5917f1f196b413eba0ae4c7fa20fc5a4685ff8de16e1d4b37bd438f95a64736f6c63430005100032000000000000000000000000afce80b19a8ce13dec0739a1aab7a028d6845eb3000000000000000000000000e2f2a5c287993345a840db3b0845fbc70f5935a5
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100935760003560e01c8063a3f5c1d211610066578063a3f5c1d2146100ff578063a453b6cf14610123578063b5bd3eb914610140578063cbe5417314610148578063db006a751461016757610093565b8063220c5bbb146100985780633ba0b9a9146100b75780636009a2d8146100d15780639bf42b3f146100f7575b600080fd5b6100b5600480360360208110156100ae57600080fd5b5035610184565b005b6100bf610382565b60408051918252519081900360200190f35b6100bf600480360360208110156100e757600080fd5b50356001600160a01b0316610388565b6100bf61039a565b6101076103a0565b604080516001600160a01b039092168252519081900360200190f35b6100bf6004803603602081101561013957600080fd5b50356103af565b6100bf6105f4565b6100b56004803603602081101561015e57600080fd5b503515156105fa565b6100bf6004803603602081101561017d57600080fd5b50356106ae565b61018c6108bc565b6001600160a01b0316336001600160a01b0316146101f1576040805162461bcd60e51b815260206004820181905260248201527f4f6e6c7920736176696e6773206d616e616765722063616e2065786563757465604482015290519081900360640190fd5b6000811161023f576040805162461bcd60e51b81526020600482015260166024820152754d757374206465706f73697420736f6d657468696e6760501b604482015290519081900360640190fd5b600154604080516323b872dd60e01b81523360048201523060248201526044810184905290516001600160a01b03909216916323b872dd916064808201926020929091908290030181600087803b15801561029957600080fd5b505af11580156102ad573d6000803e3d6000fd5b505050506040513d60208110156102c357600080fd5b505161030c576040805162461bcd60e51b81526020600482015260136024820152724d757374207265636569766520746f6b656e7360681b604482015290519081900360640190fd5b60025461031f908263ffffffff61095916565b6002556003541561037f5760035460025461033f9163ffffffff6109bc16565b6004819055604080519182526020820183905280517fc8d1043f24843c0a1c9251fdc30017d84e87498fbcf232af9f86816b5e182bde9281900390910190a15b50565b60045481565b60056020526000908152604090205481565b60025481565b6000546001600160a01b031681565b60008082116103fe576040805162461bcd60e51b81526020600482015260166024820152754d757374206465706f73697420736f6d657468696e6760501b604482015290519081900360640190fd5b60065460ff1615610479576104116108bc565b60015460408051636515eff360e11b81526001600160a01b0392831660048201529051929091169163ca2bdfe69160248082019260009290919082900301818387803b15801561046057600080fd5b505af1158015610474573d6000803e3d6000fd5b505050505b600154604080516323b872dd60e01b81523360048201523060248201526044810185905290516001600160a01b03909216916323b872dd916064808201926020929091908290030181600087803b1580156104d357600080fd5b505af11580156104e7573d6000803e3d6000fd5b505050506040513d60208110156104fd57600080fd5b5051610546576040805162461bcd60e51b81526020600482015260136024820152724d757374207265636569766520746f6b656e7360681b604482015290519081900360640190fd5b600254610559908363ffffffff61095916565b600255610565826109f1565b60035490915061057b908263ffffffff61095916565b6003553360009081526005602052604090205461059e908263ffffffff61095916565b33600081815260056020908152604091829020939093558051858152928301849052805191927f1a96ef469e332471886959f90a71ae924792a05ad7eea4e43a1c29becdf238ed929081900390910190a2919050565b60035481565b610602610a08565b6001600160a01b0316336001600160a01b031614610667576040805162461bcd60e51b815260206004820152601960248201527f4f6e6c7920676f7665726e6f722063616e206578656375746500000000000000604482015290519081900360640190fd5b6006805482151560ff19909116811790915560408051918252517fb9fdedbd8818c7929701eadc08c748a262fb39d9237b27537ae1809061e305f69181900360200190a150565b6000808211610704576040805162461bcd60e51b815260206004820152601760248201527f4d75737420776974686472617720736f6d657468696e67000000000000000000604482015290519081900360640190fd5b3360009081526005602052604090205482811015610760576040805162461bcd60e51b8152602060048201526014602482015273536176657220686173206e6f206372656469747360601b604482015290519081900360640190fd5b610770818463ffffffff610a5716565b33600090815260056020526040902055600354610793908463ffffffff610a5716565b60035561079f83610a99565b6002549092506107b5908363ffffffff610a5716565b6002556001546040805163a9059cbb60e01b81523360048201526024810185905290516001600160a01b039092169163a9059cbb916044808201926020929091908290030181600087803b15801561080c57600080fd5b505af1158015610820573d6000803e3d6000fd5b505050506040513d602081101561083657600080fd5b505161087c576040805162461bcd60e51b815260206004820152601060248201526f4d7573742073656e6420746f6b656e7360801b604482015290519081900360640190fd5b6040805184815260208101849052815133927fa4feb388d266c39bec6f79f16c3a7dba32e12d9688ddbb14493d46ce4c1ce657928290030190a250919050565b60008054604080516385acd64160e01b81527f12fe936c77a1e196473c4314f3bed8eeac1d757b319abb85bdda70df35511bf1600482015290516001600160a01b03909216916385acd64191602480820192602092909190829003018186803b15801561092857600080fd5b505afa15801561093c573d6000803e3d6000fd5b505050506040513d602081101561095257600080fd5b5051905090565b6000828201838110156109b3576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b6000806109d784670de0b6b3a764000063ffffffff610ab016565b90506109e9818463ffffffff610b0916565b949350505050565b60006109b6600454836109bc90919063ffffffff16565b60008060009054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b15801561092857600080fd5b60006109b383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610b4b565b60006109b660045483610be290919063ffffffff16565b600082610abf575060006109b6565b82820282848281610acc57fe5b04146109b35760405162461bcd60e51b8152600401808060200182810382526021815260200180610c8b6021913960400191505060405180910390fd5b60006109b383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610bf7565b60008184841115610bda5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610b9f578181015183820152602001610b87565b50505050905090810190601f168015610bcc5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60006109b38383670de0b6b3a7640000610c5c565b60008183610c465760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610b9f578181015183820152602001610b87565b506000838581610c5257fe5b0495945050505050565b600080610c6f858563ffffffff610ab016565b9050610c81818463ffffffff610b0916565b9594505050505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a265627a7a72315820b5f2ac5917f1f196b413eba0ae4c7fa20fc5a4685ff8de16e1d4b37bd438f95a64736f6c63430005100032
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000afce80b19a8ce13dec0739a1aab7a028d6845eb3000000000000000000000000e2f2a5c287993345a840db3b0845fbc70f5935a5
-----Decoded View---------------
Arg [0] : _nexus (address): 0xAFcE80b19A8cE13DEc0739a1aaB7A028d6845Eb3
Arg [1] : _mUSD (address): 0xe2f2a5C287993345a840Db3B0845fbC70f5935a5
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000afce80b19a8ce13dec0739a1aab7a028d6845eb3
Arg [1] : 000000000000000000000000e2f2a5c287993345a840db3b0845fbc70f5935a5
Deployed Bytecode Sourcemap
22290:6634:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;22290:6634:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24670:754;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;24670:754:0;;:::i;:::-;;23277:34;;;:::i;:::-;;;;;;;;;;;;;;;;23359:49;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;23359:49:0;-1:-1:-1;;;;;23359:49:0;;:::i;22950:27::-;;;:::i;3105:19::-;;;:::i;:::-;;;;-1:-1:-1;;;;;3105:19:0;;;;;;;;;;;;;;26130:972;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;26130:972:0;;:::i;23031:27::-;;;:::i;23986:217::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;23986:217:0;;;;:::i;27486:777::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;27486:777:0;;:::i;24670:754::-;23813:17;:15;:17::i;:::-;-1:-1:-1;;;;;23799:31:0;:10;-1:-1:-1;;;;;23799:31:0;;23791:76;;;;;-1:-1:-1;;;23791:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24792:1;24782:7;:11;24774:46;;;;;-1:-1:-1;;;24774:46:0;;;;;;;;;;;;-1:-1:-1;;;24774:46:0;;;;;;;;;;;;;;;24895:4;;:53;;;-1:-1:-1;;;24895:53:0;;24913:10;24895:53;;;;24933:4;24895:53;;;;;;;;;;;;-1:-1:-1;;;;;24895:4:0;;;;:17;;:53;;;;;;;;;;;;;;;:4;;:53;;;5:2:-1;;;;30:1;27;20:12;5:2;24895:53:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;24895:53:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;24895:53:0;24887:85;;;;;-1:-1:-1;;;24887:85:0;;;;;;;;;;;;-1:-1:-1;;;24887:85:0;;;;;;;;;;;;;;;24998:12;;:25;;25015:7;24998:25;:16;:25;:::i;:::-;24983:12;:40;25111:12;;:16;25108:309;;25328:12;;25302;;:39;;;:25;:39;:::i;:::-;25287:12;:54;;;25363:42;;;;;;;;;;;;;;;;;;;;;;;;25108:309;24670:754;:::o;23277:34::-;;;;:::o;23359:49::-;;;;;;;;;;;;;:::o;22950:27::-;;;;:::o;3105:19::-;;;-1:-1:-1;;;;;3105:19:0;;:::o;26130:972::-;26207:21;26264:1;26254:7;:11;26246:46;;;;;-1:-1:-1;;;26246:46:0;;;;;;;;;;;;-1:-1:-1;;;26246:46:0;;;;;;;;;;;;;;;26308:26;;;;26305:221;;;26452:17;:15;:17::i;:::-;26508:4;;26436:78;;;-1:-1:-1;;;26436:78:0;;-1:-1:-1;;;;;26508:4:0;;;26436:78;;;;;;:63;;;;;;;:78;;;;;26508:4;;26436:78;;;;;;;;26508:4;26436:63;:78;;;5:2:-1;;;;30:1;27;20:12;5:2;26436:78:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;26436:78:0;;;;26305:221;26594:4;;:53;;;-1:-1:-1;;;26594:53:0;;26612:10;26594:53;;;;26632:4;26594:53;;;;;;;;;;;;-1:-1:-1;;;;;26594:4:0;;;;:17;;:53;;;;;;;;;;;;;;;:4;;:53;;;5:2:-1;;;;30:1;27;20:12;5:2;26594:53:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;26594:53:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;26594:53:0;26586:85;;;;;-1:-1:-1;;;26586:85:0;;;;;;;;;;;;-1:-1:-1;;;26586:85:0;;;;;;;;;;;;;;;26697:12;;:25;;26714:7;26697:25;:16;:25;:::i;:::-;26682:12;:40;26820:24;26836:7;26820:15;:24::i;:::-;26870:12;;26804:40;;-1:-1:-1;26870:31:0;;26804:40;26870:31;:16;:31;:::i;:::-;26855:12;:46;26994:10;26979:26;;;;:14;:26;;;;;;:45;;27010:13;26979:45;:30;:45;:::i;:::-;26965:10;26950:26;;;;:14;:26;;;;;;;;;:74;;;;27042:52;;;;;;;;;;;;;26965:10;;27042:52;;;;;;;;;;;26130:972;;;:::o;23031:27::-;;;;:::o;23986:217::-;3580:11;:9;:11::i;:::-;-1:-1:-1;;;;;3566:25:0;:10;-1:-1:-1;;;;;3566:25:0;;3558:63;;;;;-1:-1:-1;;;3558:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;24097:26;:37;;;;;-1:-1:-1;;24097:37:0;;;;;;;;24150:45;;;;;;;;;;;;;;;;23986:217;:::o;27486:777::-;27556:22;27615:1;27604:8;:12;27596:48;;;;;-1:-1:-1;;;27596:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;27695:10;27657:20;27680:26;;;:14;:26;;;;;;27725:24;;;;27717:57;;;;;-1:-1:-1;;;27717:57:0;;;;;;;;;;;;-1:-1:-1;;;27717:57:0;;;;;;;;;;;;;;;27816:26;:12;27833:8;27816:26;:16;:26;:::i;:::-;27802:10;27787:26;;;;:14;:26;;;;;:55;27868:12;;:26;;27885:8;27868:26;:16;:26;:::i;:::-;27853:12;:41;27970:25;27986:8;27970:15;:25::i;:::-;28021:12;;27953:42;;-1:-1:-1;28021:32:0;;27953:42;28021:32;:16;:32;:::i;:::-;28006:12;:47;28122:4;;:41;;;-1:-1:-1;;;28122:41:0;;28136:10;28122:41;;;;;;;;;;;;-1:-1:-1;;;;;28122:4:0;;;;:13;;:41;;;;;;;;;;;;;;;:4;;:41;;;5:2:-1;;;;30:1;27;20:12;5:2;28122:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;28122:41:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;28122:41:0;28114:70;;;;;-1:-1:-1;;;28114:70:0;;;;;;;;;;;;-1:-1:-1;;;28114:70:0;;;;;;;;;;;;;;;28202:53;;;;;;;;;;;;;;28218:10;;28202:53;;;;;;;;27486:777;;;;:::o;6339:121::-;6389:7;6416:5;;:36;;;-1:-1:-1;;;6416:36:0;;2151:66;6416:36;;;;;;-1:-1:-1;;;;;6416:5:0;;;;:15;;:36;;;;;;;;;;;;;;;:5;:36;;;5:2:-1;;;;30:1;27;20:12;5:2;6416:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;6416:36:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;6416:36:0;;-1:-1:-1;6339:121:0;:::o;9751:181::-;9809:7;9841:5;;;9865:6;;;;9857:46;;;;;-1:-1:-1;;;9857:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;9923:1;-1:-1:-1;9751:181:0;;;;;:::o;18513:182::-;18607:7;;18644:17;:1;14912:4;18644:17;:5;:17;:::i;:::-;18632:29;-1:-1:-1;18679:8:0;18632:29;18685:1;18679:8;:5;:8;:::i;:::-;18672:15;18513:182;-1:-1:-1;;;;18513:182:0:o;28409:177::-;28501:15;28544:34;28565:12;;28544:7;:20;;:34;;;;:::i;4583:95::-;4627:7;4654:5;;;;;;;;;-1:-1:-1;;;;;4654:5:0;-1:-1:-1;;;;;4654:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;10207:136:0;10265:7;10292:43;10296:1;10299;10292:43;;;;;;;;;;;;;;;;;:3;:43::i;28733:188::-;28826:20;28879:34;28900:12;;28879:8;:20;;:34;;;;:::i;11123:471::-;11181:7;11426:6;11422:47;;-1:-1:-1;11456:1:0;11449:8;;11422:47;11493:5;;;11497:1;11493;:5;:1;11517:5;;;;;:10;11509:56;;;;-1:-1:-1;;;11509:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12062:132;12120:7;12147:39;12151:1;12154;12147:39;;;;;;;;;;;;;;;;;:3;:39::i;10680:192::-;10766:7;10802:12;10794:6;;;;10786:29;;;;-1:-1:-1;;;10786:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;10786:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;10838:5:0;;;10680:192::o;16581:167::-;16674:7;16706:34;16723:1;16726;14912:4;16706:16;:34::i;12724:345::-;12810:7;12912:12;12905:5;12897:28;;;;-1:-1:-1;;;12897:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27:10:-1;;8:100;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;12897:28:0;;12936:9;12952:1;12948;:5;;;;;;;12724:345;-1:-1:-1;;;;;12724:345:0:o;17221:196::-;17334:7;;17371:8;:1;17377;17371:8;:5;:8;:::i;:::-;17359:20;-1:-1:-1;17397:12:0;17359:20;17403:5;17397:12;:5;:12;:::i;:::-;17390:19;17221:196;-1:-1:-1;;;;;17221:196:0:o
Swarm Source
bzzr://b5f2ac5917f1f196b413eba0ae4c7fa20fc5a4685ff8de16e1d4b37bd438f95a
Loading...
Loading
Loading...
Loading
OVERVIEW
The mUSD Savings Contract allows savers to earn yield on their mUSD. It distributes the inflation generated from the mUSD basket to Savers proportionately to their credit balance. These redeemable credits are issued in return for mUSD deposits, based on the current (ever increasing) exchange rate.Net Worth in USD
$31,336.29
Net Worth in ETH
16.915367
Token Allocations
MUSD
100.00%
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ETH | 100.00% | $0.99833 | 31,388.7101 | $31,336.29 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.