Skip to content

Commit

Permalink
Add mock connector instances and patch overflow issue
Browse files Browse the repository at this point in the history
  • Loading branch information
superduck35 committed Jan 14, 2021
1 parent 94f04ae commit 022c5cc
Show file tree
Hide file tree
Showing 6 changed files with 408 additions and 40 deletions.
6 changes: 2 additions & 4 deletions contracts/savings/SavingsContract.sol
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ contract SavingsContract is
// How often do we allow pokes
uint256 constant private POKE_CADENCE = 4 hours;
// Max APY generated on the capital in the connector
uint256 constant private MAX_APY = 2e18;
uint256 constant private MAX_APY = 4e18;
uint256 constant private SECONDS_IN_YEAR = 365 days;

// Add these constants to bytecode at deploytime
Expand Down Expand Up @@ -570,8 +570,6 @@ contract SavingsContract is
}
}
// Else ideal == connectorBalance (e.g. 0), do nothing
// TODO - consider if this will actually work.. maybe check that new rawBalance is
// fully withdrawn?
require(connector_.checkBalance() >= ideal, "Enforce system invariant");

// 4i. Refresh exchange rate and emit event
Expand Down Expand Up @@ -606,7 +604,7 @@ contract SavingsContract is
uint256 newExchangeRate = _calcExchangeRate(_realSum, _totalCredits);
exchangeRate = newExchangeRate;

emit ExchangeRateUpdated(newExchangeRate, _realSum.sub(totalCredited));
emit ExchangeRateUpdated(newExchangeRate, _realSum > totalCredited ? _realSum.sub(totalCredited) : 0);
}

/**
Expand Down
7 changes: 0 additions & 7 deletions contracts/z_mocks/savings/MockConnector.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import { IConnector } from "../../savings/peripheral/IConnector.sol";
import { StableMath, SafeMath } from "../../shared/StableMath.sol";


// Turn this into a real mock by issuing shares on deposit that go up in value

contract MockConnector is IConnector {

using StableMath for uint256;
Expand Down Expand Up @@ -46,10 +44,5 @@ contract MockConnector is IConnector {

function checkBalance() external view returns (uint256) {
return deposited;
// return StableMath.max(deposited, )
}

// function _bumpSharePrice() internal private {
// sharePrice = sharePrice.mul(1001).div(1000);
// }
}
67 changes: 67 additions & 0 deletions contracts/z_mocks/savings/MockLendingConnector.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
pragma solidity 0.5.16;

import { IERC20, ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { IConnector } from "../../savings/peripheral/IConnector.sol";
import { StableMath, SafeMath } from "../../shared/StableMath.sol";


contract MockLendingConnector is IConnector {

using StableMath for uint256;
using SafeMath for uint256;

address save;
address mUSD;

uint256 lastValue;
uint256 lastAccrual;
uint256 constant perSecond = 31709791983;

constructor(
address _save,
address _mUSD
) public {
save = _save;
mUSD = _mUSD;
}

modifier onlySave() {
require(save == msg.sender, "Only SAVE can call this");
_;
}

modifier _accrueValue() {
uint256 currentTime = block.timestamp;
if(lastAccrual != 0){
uint256 timeDelta = currentTime.sub(lastAccrual);
uint256 interest = timeDelta.mul(perSecond);
uint256 newValue = lastValue.mulTruncate(interest);
lastValue += newValue;
}
lastAccrual = currentTime;
_;
}

function poke() external _accrueValue {

}

function deposit(uint256 _amount) external _accrueValue onlySave {
IERC20(mUSD).transferFrom(save, address(this), _amount);
lastValue += _amount;
}

function withdraw(uint256 _amount) external _accrueValue onlySave {
IERC20(mUSD).transfer(save, _amount);
lastValue -= _amount;
}

function withdrawAll() external _accrueValue onlySave {
IERC20(mUSD).transfer(save, lastValue);
lastValue -= lastValue;
}

function checkBalance() external view returns (uint256) {
return lastValue;
}
}
101 changes: 101 additions & 0 deletions contracts/z_mocks/savings/MockVaultConnector.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
pragma solidity 0.5.16;

import { IERC20, ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { IConnector } from "../../savings/peripheral/IConnector.sol";
import { StableMath, SafeMath } from "../../shared/StableMath.sol";


// Use this as a template for any volatile vault implementations, to ensure
// connector invariant is held
contract MockVaultConnector is IConnector {

using StableMath for uint256;
using SafeMath for uint256;

address save;
address mUSD;

uint256 trackedB;
uint256 realB;
uint256 lastAccrual;
uint256 constant perSecond = 31709791983;

constructor(
address _save,
address _mUSD
) public {
save = _save;
mUSD = _mUSD;
}

modifier onlySave() {
require(save == msg.sender, "Only SAVE can call this");
_;
}

// realBalance
// trackedBalance

// step 1: deposit 100
// - log trackedB amount
// step 2: check Balance
// - get real balance
// - trackedB > realB ? trackedB : realB
// step 3: realB goes to 100.1
// step 4: withdraw 10
// - checkBalance must be >= 90.1 afterwards
// - trackedB = 90.1
// - trackedB > realB ? trackedB : realB
// stpe 5: withdraw 10
// - checkedBalance must be >= 80.1 after
// - trackedB = 80.1

modifier _accrueValue() {
_;
uint256 currentTime = block.timestamp;
if(lastAccrual != 0){
uint256 timeDelta = currentTime.sub(lastAccrual);
uint256 interest = timeDelta.mul(perSecond);
uint256 newValue = realB.mulTruncate(interest);
realB = newValue;
}
lastAccrual = currentTime;
}

function poke() external _accrueValue {

}

function deposit(uint256 _amount) external _accrueValue onlySave {
uint256 checkedB = _checkBalanceExt();
trackedB = checkedB.add(_amount);

IERC20(mUSD).transferFrom(save, address(this), _amount);
realB += _amount.mul(995).div(1000);
}

function withdraw(uint256 _amount) external _accrueValue onlySave {
uint256 checkedB = _checkBalanceExt();
trackedB = checkedB.sub(_amount);

IERC20(mUSD).transfer(save, _amount);
realB -= _amount.mul(1005).div(1000);
}

function withdrawAll() external _accrueValue onlySave {
trackedB = 0;

IERC20(mUSD).transfer(save, realB);
realB -= realB;
}

function checkBalance() external view returns (uint256) {
return _checkBalanceExt();
}

// a call to checkBalance followed by a deposit/withdraw then another checkbalance
// will always yield a sideways or increase
function _checkBalanceExt() internal view returns (uint256) {
return trackedB > realB ? trackedB : realB;
}
}
Loading

0 comments on commit 022c5cc

Please sign in to comment.