Smart contract reference#

The smart contract source code can be found on GitHub.

Architecture overview#

Each 88mph pool consists of 6 smart contracts:

  • DInterest: The main smart contract that users interact with. Handles depositing, withdrawing, and keeping track of deposits. Emits all of the events used in the subgraph.
  • FeeModel: Determines the fee strategy of 88mph, as well as who receives the fees.
  • MoneyMarket: A wrapper for interacting with yield-generating protocols, and stores all of the user funds. Requires a different one for each protocol.
  • InterestOracle: An oracle for the interest rate of the underlying yield-generating protocol.
  • NFT: Two non-fungible ERC721 tokens, used for representing ownership of deposits and bonds.

Globally 88mph has the following contracts for handling things related to the MPH token:

  • MPHToken: The MPH ERC-20 token contract itself.
  • MPHMinter: Responsible for minting & taking back MPH tokens for depositors & bond buyers.
  • Dumper: Responsible for accumulating the protocol fees & yield-farming rewards generated by 88mph pools and exchanging them for DAI.
  • Rewards: The MPH rewards staking contract for distributing the protocol fees & yield-farming rewards.

API reference#

DInterest#

State changing functions#

function deposit(uint256 amount, uint256 maturationTimestamp) external#

Creates a single deposit for the caller.

  • amount: The amount of stablecoin to deposit. The caller should have already approved the contract to spend this much stablecoin before calling this function. Scaled by .
  • maturationTimestamp: The Unix timestamp at and after which the deposit will be able to be withdrawn. In seconds.
function withdraw(uint256 depositID, uint256 fundingID) external#

Withdraws a single deposit for the caller. The caller must own the deposit NFT with ID depositID.

  • depositID: The index of the deposit to be withdrawn in the deposits array plus 1.
  • fundingID: The index of the funding object that funded the deposit's debt in the fundingList array plus 1. It can be found using our subgraph.
Important note#

Withdrawing may fail if the 88mph pool has failed to generate enough interest from the underlying money market to cover the promised fixed-rate interest, and no one has funded the difference by buying bonds. This is the main risk of depositing into 88mph.

function earlyWithdraw(uint256 depositID, uint256 fundingID) external#

Withdraws a single deposit for the caller, before the maturation timestamp. The caller must own the deposit NFT with ID depositID.

  • depositID: The index of the deposit to be withdrawn in the deposits array plus 1.
  • fundingID: The index of the funding object that funded the deposit's debt in the fundingList array plus 1. It can be found using our subgraph.
function multiDeposit(uint256[] calldata amountList, uint256[] calldata maturationTimestampList) external#

Deposits multiple deposits for the caller. The values at each index in each array will be combined to create a single deposit.

  • amountList: An array of the amounts of stablecoin to deposit. The caller should have already approved the contract to spend this much stablecoin before calling this function. Scaled by .
  • maturationTimestampList: An array of the Unix timestamps at and after which the deposits will be able to be withdrawn. In seconds.
Input size limit#

The maximum recommended number of deposits is 20.

function multiWithdraw(uint256[] calldata depositIDList, uint256[] calldata fundingIDList) external#

Withdraws multiple deposits for the caller. The caller must own the deposit NFTs with IDs in depositIDList.

  • depositIDList: The indices of the deposits to be withdrawn in the deposits array plus 1.
  • fundingIDList: The indices of the funding objects that funded the deposit's debt in the fundingList array plus 1. It can be found using our subgraph.
Input size limit#

The maximum recommended number of deposits is 100.

Important note#

Withdrawing may fail if the 88mph pool has failed to generate enough interest from the underlying money market to cover the promised fixed-rate interest, and no one has funded the difference. This is the main risk of depositing into 88mph.

function multiEarlyWithdraw(uint256[] calldata depositIDList, uint256[] calldata fundingIDList) external#

Withdraws multiple deposits for the caller, before the maturation timestamp. The caller must own the deposit NFTs with IDs in depositIDList.

  • depositIDList: The indices of the deposits to be withdrawn in the deposits array plus 1.
  • fundingIDList: The indices of the funding objects that funded the deposit's debt in the fundingList array plus 1. It can be found using our subgraph.
Input size limit#

The maximum recommended number of deposits is 50.

function fundAll() external#

Allows the caller to fund all of the existing deficit of the 88mph pool. In exchange, the caller receives a funding NFT, and the interest generated by the deposits the caller funded will be sent to the owner of the NFT whenever a deposit they funded is withdrawn.

Before calling this function, the caller must approve at least the deficit amount of stablecoin to the DInterest contract. This amount may be obtained using surplus(). To avoid the transaction being reverted, it is recommended to simply set the approval amount to .

function fundMultiple(uint256 toDepositID) external#

Allows the caller to fund the deficit of multiple deposits. In exchange, the caller receives a funding NFT, and the interest generated by the deposits the caller funded will be sent to the owner of the NFT whenever a deposit they funded is withdrawn.

Before calling this function, the caller must approve at least the deficit amount of stablecoin to the DInterest contract. This amount may be obtained using surplusOfDeposit(). To avoid the transaction being reverted, it is recommended to simply set the approval amount to .

  • toDepositID: Deposits with ID from (not including) lastFundedDepositID to (including) toDepositID will be funded.

Read only functions#

function getDeposit(uint256 depositID) external view returns (uint256 amount, uint256 maturationTimestamp, uint256 initialDeficit, uint256 initialMoneyMarketIncomeIndex, bool active)#

Returns info about a user deposit. The owner of the deposit is whichever Ethereum account that owns the ERC721 deposit token with id depositID.

Inputs#
  • depositID: The index of the deposit in the deposits array.
Returns#
  • uint256 amount: The amount of the deposit, in stablecoins. Scaled by .
  • uint256 maturationTimestamp: The Unix timestamp at and after which the deposit will be able to be withdrawn. In seconds.
  • uint256 interestOwed: The initial debt caused by the deposit.
  • uint256 initialMoneyMarketIncomeIndex: The value returned by moneyMarket.incomeIndex() at the time of deposit.
  • bool active: true if the deposit hasn't been withdrawn, false otherwise.
  • bool finalSurplusIsNegative: true if at the time of withdrawal the deposit had a negative surplus, false otherwise.
  • uint256 finalSurplusAmount: The amount of surplus/debt of the deposit at the time of withdrawal.
  • uint256 mintMPHAmount: The amount of MPH tokens minted to the user at the time of deposit.
  • uint256 depositTimestamp: Unix timestamp at time of deposit, in seconds.
function getFunding(uint256 fundingID) external view returns (uint256 fromDepositID, uint256 toDepositID, uint256 recordedFundedDepositAmount, uint256 recordedMoneyMarketIncomeIndex)#

Returns info about a funding. The owner of the funding (and the account who will receive the interests) is whichever Ethereum account that owns the ERC721 funding token with id fundingID.

Inputs#
  • fundingID: The index of the funding in the fundingList array.
Returns#
  • fromDepositID: Deposits with ID from (not including) fromDepositID to (including) toDepositID have their deficits funded by this funding instance.
  • toDepositID: Deposits with ID from (not including) fromDepositID to (including) toDepositID have their deficits funded by this funding instance.
  • recordedFundedDepositAmount: The current total deposit amount that is generating interest for the owner of this funding instance, in stablecoins. Scaled by .
  • recordedMoneyMarketIncomeIndex: The value returned by moneyMarket.incomeIndex() at the time of the latest withdrawal of a deposit funded by this funding instance. If no funded deposit has been withdrawn yet, this value is equal to the monet market incomeIndex at the time of the funding instance's creation.
function MinDepositPeriod() external view returns (uint256)#

Returns the minimum deposit period, in seconds.

function MaxDepositPeriod() external view returns (uint256)#

Returns the maximum deposit period, in seconds.

function MinDepositAmount() external view returns (uint256)#

Returns the minimum deposit amount for a single deposit in stablecoin. Scaled by .

function MaxDepositAmount() external view returns (uint256)#

Returns the maximum deposit amount for a single deposit in stablecoin. Scaled by .

function totalDeposit() external view returns (uint256)#

Returns the total deposited amount of stablecoin. Scaled by .

function moneyMarket() external view returns (address)#

Returns the address of MoneyMarket.

function stablecoin() external view returns (address)#

Returns the address of the stablecoin used.

function feeModel() external view returns (address)#

Returns the address of FeeModel.

function interestModel() external view returns (address)#

Returns the address of InterestModel.

function interestOracle() external view returns (address)#

Returns the address of InterestOracle.

function depositNFT() external view returns (address)#

Returns the address of the ERC721 deposit token.

function fundingNFT() external view returns (address)#

Returns the address of ERC721 funding token.

function calculateInterestAmount(uint256 depositAmount, uint256 depositPeriodInSeconds) external view returns (uint256 interestAmount)#

Returns the interest amount given the deposit amount and period.

Inputs#
  • depositAmount: The amount of the deposit in stablecoin. Scaled by .
  • depositPeriodInSeconds: The length of the deposit's deposit period, in seconds.
function surplus() external view returns (bool isNegative, uint256 surplusAmount)#

Returns the surplus value of the pool over the owed deposits.

Returns#
  • isNegative: Whether the surplus is negative. A negative surplus means there's a deficit.
  • surplusAmount: Amount of the pool's surplus, in stablecoins. Scaled by .
function surplusOfDeposit(uint256 depositID) external view returns (bool isNegative, uint256 surplusAmount)#

Returns the surplus value of a particular deposit. Does not include funding.

Inputs#
  • depositID: The index of the deposit to be withdrawn in the deposits array plus 1.
Returns#
  • isNegative: Whether the surplus is negative. A negative surplus means there's a deficit.
  • surplusAmount: Amount of the pool's surplus, in stablecoins. Scaled by .
function depositsLength() external view returns (uint256)#

Returns the length of the deposits array.

function fundingListLength() external view returns (address)#

Returns the length of the fundingList array.

function depositIsFunded(uint256 depositID) external view returns (bool)#
Inputs#
  • depositID: The index of the deposit to be withdrawn in the deposits array plus 1.
Returns#

Returns whether or not the deposit's deficit has been funded.

function latestFundedDepositID() external view returns (uint256)#

Returns the maximum ID among funded deposits. It can be assumed that all deposits with ID less than or equal to this value have been funded.

function unfundedUserDepositAmount() external view returns (uint256)#

Returns the deposited stablecoin amount whose deficit hasn't been funded. Scaled by .

FeeModel#

Read only functions#

function getFee(uint256 _txAmount) external pure returns (uint256 _feeAmount)#

Used for determining how much fee to charge from a transaction.

Inputs#
  • _txAmount: The amount of the transaction from which a fee will be taken.
Returns#
  • _feeAmount: The amount of the fee that will be taken from the transaction.
function beneficiary() external view returns (address)#

Returns the address who will receive the fees.

MoneyMarket#

State changing functions#

function deposit(uint256 amount) external#

Lends amount stablecoins to the underlying money market protocol.

Inputs#
  • amount: The amount of stablecoins to be deposited.
function withdraw(uint256 amountInUnderlying) external#

Withdraws amountInUnderlying stablecoins from the underlying money market protocol.

Inputs#
  • amountInUnderlying: The amount of stablecoins to be withdrawn.

Read only functions#

function totalValue() external returns (uint256)#

Returns the total value locked in the money market, in terms of the underlying stablecoin. Scaled by .

function incomeIndex() external returns (uint256)#

Returns an index that can be used to compute the interest generated by the money market over a period of time. Specifically, .

ZeroCouponBond#

Read only functions#

bool public initialized;
DInterest public pool;
FractionalDepositFactory public fractionalDepositFactory;
ERC20 public stablecoin;
uint256 public maturationTimestamp;
string public name;
string public symbol;
uint8 public decimals;

State changing functions#

function mintWithDepositNFT(uint256 nftID, string calldata fractionalDepositName, string calldata fractionalDepositSymbol) external returns (uint256 zeroCouponBondsAmount, FractionalDeposit fractionalDeposit)#

Mints zero coupon bond tokens using a deposit NFT.

Inputs#
  • uint256 nftID: the ID of the deposit NFT
  • string calldata fractionalDepositName: the name for the fractionalized deposit token (cosmetic)
  • string calldata fractionalDepositSymbol: the symbol for the fractionalized deposit token (cosmetic)
Return values#
  • uint256 zeroCouponBondsAmount: the amount of bonds minted
  • FractionalDeposit fractionalDeposit: the created FractionalDeposit contract for the deposit
function redeemStablecoin(uint256 amount) external returns (uint256 actualRedeemedAmount)#

Redeems zero coupon bonds for the underlying tokens. If there is not enough tokens to pay out the redemption, the max possible amount is redeemed.

Inputs#
  • uint256 amount: the amount of bonds to redeem
Return values#
  • uint256 actualRedeemedAmount: the actual redeemed underlying token amount, which may be less than the bonds redeemed
function redeemFractionalDepositShares(address fractionalDepositAddress, uint256 fundingID) external#

Withdraws the underlying deposit to allow for bond holders to redeem their bonds for the underlying tokens.

Inputs#
  • address fractionalDepositAddress: the address of the fractional deposit
  • uint256 fundingID: the ID of the floating-rate bond that funded the deposit's fixed-rate interest