Skip to content

Commit

Permalink
Migrate contracts & add husky precommits (mstable#167)
Browse files Browse the repository at this point in the history
* chore: Migrate SavingsManager and add Husky precommits

* chore: Add husky precommits

* chore: Import SavingsManager

* fix: Remove duplicate Uniswap interface

* chore: Migrate SM test cases
  • Loading branch information
superduck35 authored and naddison36 committed Apr 19, 2021
1 parent 7d1cfd6 commit aca08a8
Show file tree
Hide file tree
Showing 36 changed files with 2,773 additions and 458 deletions.
7 changes: 7 additions & 0 deletions .commitlintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
"scope-case": [2, 'always', 'lower-case'],
"subject-case": [2, 'always', 'sentence-case'],
}
}
1 change: 1 addition & 0 deletions .husky/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
_
4 changes: 4 additions & 0 deletions .husky/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

yarn commitlint --edit "$1"
4 changes: 4 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

yarn lint:fix
52 changes: 12 additions & 40 deletions contracts/feeders/InterestValidator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { IFeederPool } from "../interfaces/IFeederPool.sol";
import { PausableModule } from "../shared/PausableModule.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { YieldValidator } from "../shared/YieldValidator.sol";

/**
* @title InterestValidator
Expand All @@ -25,11 +26,6 @@ contract InterestValidator is PausableModule {
);
event GovFeeCollected(address indexed feederPool, address mAsset, uint256 amount);

// Utils to help keep interest under check
uint256 private constant SECONDS_IN_YEAR = 365 days;
// Theoretical cap on APY to avoid excess inflation
uint256 private constant MAX_APY = 15e18;

mapping(address => uint256) public lastBatchCollected;

constructor(address _nexus) PausableModule(_nexus) {}
Expand Down Expand Up @@ -60,7 +56,11 @@ contract InterestValidator is PausableModule {
if (interestCollected > 0) {
// Validate APY
uint256 apy =
_validateCollection(totalSupply, interestCollected, timeSincePreviousBatch);
YieldValidator.validateCollection(
totalSupply,
interestCollected,
timeSincePreviousBatch
);

emit InterestCollected(feeder, interestCollected, totalSupply, apy);
} else {
Expand All @@ -87,42 +87,14 @@ contract InterestValidator is PausableModule {
if (fpTokenBal > 0) {
address mAsset = IFeederPool(fPool).mAsset();
uint256 outputAmt =
IFeederPool(fPool).redeem(mAsset, fpTokenBal, (fpTokenBal * 7) / 10, savingsManager);
IFeederPool(fPool).redeem(
mAsset,
fpTokenBal,
(fpTokenBal * 7) / 10,
savingsManager
);
emit GovFeeCollected(fPool, mAsset, outputAmt);
}
}
}

/**
* @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) {
// 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 = (_timeSinceLastCollection * 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;

require(extrapolatedAPY < MAX_APY, "Interest protected from inflating past maxAPY");
}
}
3 changes: 1 addition & 2 deletions contracts/governance/ClaimableGovernor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { Governable } from "./Governable.sol";
* DATE: 2021-04-15
*/
contract ClaimableGovernor is Governable {

event GovernorChangeClaimed(address indexed proposedGovernor);
event GovernorChangeCancelled(address indexed governor, address indexed proposed);
event GovernorChangeRequested(address indexed governor, address indexed proposed);
Expand Down Expand Up @@ -67,4 +66,4 @@ contract ClaimableGovernor is Governable {
emit GovernorChangeClaimed(proposedGovernor);
proposedGovernor = address(0);
}
}
}
7 changes: 2 additions & 5 deletions contracts/governance/DelayedClaimableGovernor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { ClaimableGovernor } from "./ClaimableGovernor.sol";
* DATE: 2021-04-15
*/
contract DelayedClaimableGovernor is ClaimableGovernor {

uint256 public delay = 0;
uint256 public requestTime = 0;

Expand All @@ -22,9 +21,7 @@ contract DelayedClaimableGovernor is ClaimableGovernor {
* @param _governorAddr Initial governor
* @param _delay Delay in seconds for 2 way handshake
*/
constructor(address _governorAddr, uint256 _delay)
ClaimableGovernor(_governorAddr)
{
constructor(address _governorAddr, uint256 _delay) ClaimableGovernor(_governorAddr) {
require(_delay > 0, "Delay must be greater than zero");
delay = _delay;
}
Expand Down Expand Up @@ -54,4 +51,4 @@ contract DelayedClaimableGovernor is ClaimableGovernor {
super.claimGovernorChange();
requestTime = 0;
}
}
}
4 changes: 1 addition & 3 deletions contracts/governance/Governable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@ pragma solidity 0.8.2;
* DATE: 2021-04-15
*/
contract Governable {

event GovernorChanged(address indexed previousGovernor, address indexed newGovernor);

address private _governor;


/**
* @dev Initializes the contract setting the deployer as the initial Governor.
*/
Expand Down Expand Up @@ -67,4 +65,4 @@ contract Governable {
emit GovernorChanged(_governor, _newGovernor);
_governor = _newGovernor;
}
}
}
2 changes: 1 addition & 1 deletion contracts/interfaces/IEjector.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ pragma solidity 0.8.2;
interface IEjector {
function ejectMany(address[] calldata _users) external;

function votingLockup() view external returns (address);
function votingLockup() external view returns (address);
}
2 changes: 1 addition & 1 deletion contracts/interfaces/ISavingsManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ interface ISavingsManager {
function collectAndDistributeInterest(address _mAsset) external;

/** @dev getter for public lastBatchCollected mapping */
function lastBatchCollected(address _mAsset) view external returns (uint256);
function lastBatchCollected(address _mAsset) external view returns (uint256);
}
7 changes: 7 additions & 0 deletions contracts/masset/liquidator/ICurveMetaPool.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity 0.8.2;

interface ICurveMetaPool {
function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external returns (uint256);
function get_dy(int128 i, int128 j, uint256 dx) external view returns (uint256);
}
30 changes: 30 additions & 0 deletions contracts/masset/liquidator/ILiquidator.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity 0.8.2;

interface ILiquidator {

function createLiquidation(
address _integration,
address _sellToken,
address _bAsset,
int128 _curvePosition,
address[] calldata _uniswapPath,
uint256 _trancheAmount,
uint256 _minReturn
)
external;

function updateBasset(
address _integration,
address _bAsset,
int128 _curvePosition,
address[] calldata _uniswapPath,
uint256 _trancheAmount,
uint256 _minReturn
)
external;

function deleteLiquidation(address _integration) external;

function triggerLiquidation(address _integration) external;
}
Loading

0 comments on commit aca08a8

Please sign in to comment.