Last active
January 27, 2021 21:56
-
-
Save franckc/6fcec3a50386bbd38f9aaf1296ea0ea0 to your computer and use it in GitHub Desktop.
Deploy 12 - contracts diff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#> git diff deploy-011 master contracts | |
diff --git a/contracts/contracts/interfaces/IComptroller.sol b/contracts/contracts/interfaces/IComptroller.sol | |
new file mode 100644 | |
index 00000000..8be07f69 | |
--- /dev/null | |
+++ b/contracts/contracts/interfaces/IComptroller.sol | |
@@ -0,0 +1,9 @@ | |
+pragma solidity 0.5.11; | |
+ | |
+interface IComptroller { | |
+ /** | |
+ * @notice Claim all the comp accrued by holder in all markets | |
+ * @param holder The address to claim COMP for | |
+ */ | |
+ function claimComp(address holder) external; | |
+} | |
diff --git a/contracts/contracts/interfaces/IVault.sol b/contracts/contracts/interfaces/IVault.sol | |
index d536de1e..51f37cc4 100644 | |
--- a/contracts/contracts/interfaces/IVault.sol | |
+++ b/contracts/contracts/interfaces/IVault.sol | |
@@ -45,6 +45,10 @@ interface IVault { | |
function uniswapAddr() external view returns (address); | |
+ function setMaxSupplyDiff(uint256 _maxSupplyDiff) external; | |
+ | |
+ function maxSupplyDiff() external view returns (uint256); | |
+ | |
function supportAsset(address _asset) external; | |
function approveStrategy(address _addr) external; | |
diff --git a/contracts/contracts/mocks/MockCToken.sol b/contracts/contracts/mocks/MockCToken.sol | |
index e1fe8fa7..be64fa5b 100644 | |
--- a/contracts/contracts/mocks/MockCToken.sol | |
+++ b/contracts/contracts/mocks/MockCToken.sol | |
@@ -19,8 +19,9 @@ contract MockCToken is ICERC20, ERC20, ERC20Detailed, ERC20Mintable { | |
// underlying = cToken * exchangeRate | |
// cToken = underlying / exchangeRate | |
uint256 exchangeRate; | |
+ address public comptroller; | |
- constructor(ERC20Detailed _underlyingToken) | |
+ constructor(ERC20Detailed _underlyingToken, address _comptroller) | |
public | |
ERC20Detailed("cMock", "cMK", 8) | |
{ | |
@@ -36,6 +37,7 @@ contract MockCToken is ICERC20, ERC20, ERC20Detailed, ERC20Mintable { | |
exchangeRate = 1e18; | |
} | |
underlyingToken = _underlyingToken; | |
+ comptroller = _comptroller; | |
} | |
function mint(uint256 mintAmount) external returns (uint256) { | |
diff --git a/contracts/contracts/mocks/MockComptroller.sol b/contracts/contracts/mocks/MockComptroller.sol | |
new file mode 100644 | |
index 00000000..938ef90f | |
--- /dev/null | |
+++ b/contracts/contracts/mocks/MockComptroller.sol | |
@@ -0,0 +1,5 @@ | |
+pragma solidity 0.5.11; | |
+ | |
+contract MockComptroller { | |
+ function claimComp(address _holder) external {} | |
+} | |
diff --git a/contracts/contracts/strategies/CompoundStrategy.sol b/contracts/contracts/strategies/CompoundStrategy.sol | |
index a918be7a..91156967 100644 | |
--- a/contracts/contracts/strategies/CompoundStrategy.sol | |
+++ b/contracts/contracts/strategies/CompoundStrategy.sol | |
@@ -6,6 +6,7 @@ pragma solidity 0.5.11; | |
* @author Origin Protocol Inc | |
*/ | |
import { ICERC20 } from "./ICompound.sol"; | |
+import { IComptroller } from "../interfaces/IComptroller.sol"; | |
import { | |
IERC20, | |
InitializableAbstractStrategy | |
@@ -14,6 +15,21 @@ import { | |
contract CompoundStrategy is InitializableAbstractStrategy { | |
event SkippedWithdrawal(address asset, uint256 amount); | |
+ /** | |
+ * @dev Collect accumulated COMP and send to Vault. | |
+ */ | |
+ function collectRewardToken() external onlyVault nonReentrant { | |
+ // Claim COMP from Comptroller | |
+ ICERC20 cToken = _getCTokenFor(assetsMapped[0]); | |
+ IComptroller comptroller = IComptroller(cToken.comptroller()); | |
+ comptroller.claimComp(address(this)); | |
+ // Transfer COMP to Vault | |
+ IERC20 rewardToken = IERC20(rewardTokenAddress); | |
+ uint256 balance = rewardToken.balanceOf(address(this)); | |
+ emit RewardTokenCollected(vaultAddress, balance); | |
+ rewardToken.safeTransfer(vaultAddress, balance); | |
+ } | |
+ | |
/** | |
* @dev Deposit asset into Compound | |
* @param _asset Address of asset to deposit | |
diff --git a/contracts/contracts/strategies/ICompound.sol b/contracts/contracts/strategies/ICompound.sol | |
index cef7e170..11b50d3b 100644 | |
--- a/contracts/contracts/strategies/ICompound.sol | |
+++ b/contracts/contracts/strategies/ICompound.sol | |
@@ -58,4 +58,9 @@ interface ICERC20 { | |
* @notice Get the supply rate per block for supplying the token to Compound. | |
*/ | |
function supplyRatePerBlock() external view returns (uint256); | |
+ | |
+ /** | |
+ * @notice Address of the Compound Comptroller. | |
+ */ | |
+ function comptroller() external view returns (address); | |
} | |
diff --git a/contracts/contracts/strategies/ICurvePool.sol b/contracts/contracts/strategies/ICurvePool.sol | |
index 975ff0f7..b4c945c3 100644 | |
--- a/contracts/contracts/strategies/ICurvePool.sol | |
+++ b/contracts/contracts/strategies/ICurvePool.sol | |
@@ -1,7 +1,7 @@ | |
pragma solidity 0.5.11; | |
interface ICurvePool { | |
- function get_virtual_price() external returns (uint256); | |
+ function get_virtual_price() external view returns (uint256); | |
function add_liquidity(uint256[3] calldata _amounts, uint256 _min) external; | |
diff --git a/contracts/contracts/strategies/ThreePoolStrategy.sol b/contracts/contracts/strategies/ThreePoolStrategy.sol | |
index aa2fb950..f9e60f4e 100644 | |
--- a/contracts/contracts/strategies/ThreePoolStrategy.sol | |
+++ b/contracts/contracts/strategies/ThreePoolStrategy.sol | |
@@ -34,7 +34,7 @@ contract ThreePoolStrategy is InitializableAbstractStrategy { | |
* @param _vaultAddress Address of the vault | |
* @param _rewardTokenAddress Address of CRV | |
* @param _asset Address of the supported asset | |
- * @param _pToken Correspond platform token addres (i.e. 3Crv) | |
+ * @param _pToken Correspond platform token address (i.e. 3Crv) | |
* @param _crvGaugeAddress Address of the Curve DAO gauge for this pool | |
* @param _crvMinterAddress Address of the CRV minter for rewards | |
*/ | |
@@ -196,16 +196,19 @@ contract ThreePoolStrategy is InitializableAbstractStrategy { | |
view | |
returns (uint256 balance) | |
{ | |
+ require(assetToPToken[_asset] != address(0), "Unsupported asset"); | |
// LP tokens in this contract. This should generally be nothing as we | |
// should always stake the full balance in the Gauge, but include for | |
// safety | |
(, , uint256 totalPTokens) = _getTotalPTokens(); | |
- balance = 0; | |
- if (totalPTokens > 0) { | |
- balance += ICurvePool(platformAddress).calc_withdraw_one_coin( | |
- totalPTokens, | |
- poolCoinIndex | |
- ); | |
+ ICurvePool curvePool = ICurvePool(platformAddress); | |
+ | |
+ uint256 pTokenTotalSupply = IERC20(assetToPToken[_asset]).totalSupply(); | |
+ if (pTokenTotalSupply > 0) { | |
+ uint256 curveBalance = IERC20(_asset).balanceOf(address(curvePool)); | |
+ if (curveBalance > 0) { | |
+ balance = totalPTokens.mul(curveBalance).div(pTokenTotalSupply); | |
+ } | |
} | |
} | |
diff --git a/contracts/contracts/token/OUSD.sol b/contracts/contracts/token/OUSD.sol | |
index dcabf171..74626651 100644 | |
--- a/contracts/contracts/token/OUSD.sol | |
+++ b/contracts/contracts/token/OUSD.sol | |
@@ -256,7 +256,7 @@ contract OUSD is Initializable, InitializableERC20Detailed, Governable { | |
* @dev Mints new tokens, increasing totalSupply. | |
*/ | |
function mint(address _account, uint256 _amount) external onlyVault { | |
- return _mint(_account, _amount); | |
+ _mint(_account, _amount); | |
} | |
/** | |
@@ -296,7 +296,7 @@ contract OUSD is Initializable, InitializableERC20Detailed, Governable { | |
* @dev Burns tokens, decreasing totalSupply. | |
*/ | |
function burn(address account, uint256 amount) external onlyVault { | |
- return _burn(account, amount); | |
+ _burn(account, amount); | |
} | |
/** | |
@@ -312,6 +312,9 @@ contract OUSD is Initializable, InitializableERC20Detailed, Governable { | |
*/ | |
function _burn(address _account, uint256 _amount) internal nonReentrant { | |
require(_account != address(0), "Burn from the zero address"); | |
+ if (_amount == 0) { | |
+ return; | |
+ } | |
bool isNonRebasingAccount = _isNonRebasingAccount(_account); | |
uint256 creditAmount = _amount.mulTruncate(_creditsPerToken(_account)); | |
@@ -361,44 +364,16 @@ contract OUSD is Initializable, InitializableERC20Detailed, Governable { | |
} | |
/** | |
- * @dev Is an account's balance non-rebasing, i.e. does not alter with rebases. | |
- * By default contracts are non-rebasing and EOA's are rebasing. | |
- * Or the address could have chosen to override this. | |
+ * @dev Is an account using rebasing accounting or non-rebasing accounting? | |
+ * Also, ensure contracts are non-rebasing if they have not opted in. | |
* @param _account Address of the account. | |
*/ | |
function _isNonRebasingAccount(address _account) internal returns (bool) { | |
- RebaseOptions accountRebaseState = rebaseState[_account]; | |
- if (accountRebaseState == RebaseOptions.OptIn) { | |
- // The address has chosen to be rebasing. | |
- return false; | |
- } else if (accountRebaseState == RebaseOptions.OptOut) { | |
- // The address has chosen to be non-rebasing. | |
- return true; | |
- } else { | |
- // The address has not chosen explicitly, so use the default | |
- // for its type. | |
- if (Address.isContract(_account)) { | |
- // Contracts default to be non-rebasing. | |
- | |
- // Migrate if needed, making sure the rebasing/non-rebasing | |
- // supply is updated and fixed credits per token is set | |
- // for this account. | |
- _ensureRebasingMigration(_account); | |
- return true; | |
- } else { | |
- // User accounts default to be rebasing. | |
- | |
- // Disallow contracts from interacting with OUSD if the following | |
- // sequence has occurred: The contract has self-destructed, been | |
- // recreated at the same address with CREATE2, and then is interacting | |
- // with OUSD again from the contract's constructor. | |
- require( | |
- nonRebasingCreditsPerToken[_account] == 0, | |
- "Previous Contract" | |
- ); | |
- return false; | |
- } | |
+ bool isContract = Address.isContract(_account); | |
+ if (isContract && rebaseState[_account] == RebaseOptions.NotSet) { | |
+ _ensureRebasingMigration(_account); | |
} | |
+ return nonRebasingCreditsPerToken[_account] > 0; | |
} | |
/** | |
diff --git a/contracts/contracts/vault/VaultAdmin.sol b/contracts/contracts/vault/VaultAdmin.sol | |
index e96d85ec..e9f5f3a7 100644 | |
--- a/contracts/contracts/vault/VaultAdmin.sol | |
+++ b/contracts/contracts/vault/VaultAdmin.sol | |
@@ -12,12 +12,12 @@ import { IUniswapV2Router } from "../interfaces/uniswap/IUniswapV2Router02.sol"; | |
contract VaultAdmin is VaultStorage { | |
/** | |
- * @dev Verifies that the caller is the Vault or Governor. | |
+ * @dev Verifies that the caller is the Vault, Governor, or Strategist. | |
*/ | |
- modifier onlyVaultOrGovernor() { | |
+ modifier onlyVaultOrGovernorOrStrategist() { | |
require( | |
- msg.sender == address(this) || isGovernor(), | |
- "Caller is not the Vault or Governor" | |
+ msg.sender == address(this) || msg.sender == strategistAddr || isGovernor(), | |
+ "Caller is not the Vault, Governor, or Strategist" | |
); | |
_; | |
} | |
@@ -240,7 +240,7 @@ contract VaultAdmin is VaultStorage { | |
/** | |
* @dev Set the deposit paused flag to true to prevent rebasing. | |
*/ | |
- function pauseRebase() external onlyGovernor { | |
+ function pauseRebase() external onlyGovernorOrStrategist { | |
rebasePaused = true; | |
emit RebasePaused(); | |
} | |
@@ -264,7 +264,7 @@ contract VaultAdmin is VaultStorage { | |
/** | |
* @dev Set the deposit paused flag to false to enable capital movement. | |
*/ | |
- function unpauseCapital() external onlyGovernorOrStrategist { | |
+ function unpauseCapital() external onlyGovernor { | |
capitalPaused = false; | |
emit CapitalUnpaused(); | |
} | |
@@ -283,6 +283,7 @@ contract VaultAdmin is VaultStorage { | |
external | |
onlyGovernor | |
{ | |
+ require(!assets[_asset].isSupported, "Only unsupported assets"); | |
IERC20(_asset).safeTransfer(governor(), _amount); | |
} | |
@@ -290,7 +291,7 @@ contract VaultAdmin is VaultStorage { | |
* @dev Collect reward tokens from all strategies and swap for supported | |
* stablecoin via Uniswap | |
*/ | |
- function harvest() external onlyGovernor { | |
+ function harvest() external onlyGovernorOrStrategist { | |
for (uint256 i = 0; i < allStrategies.length; i++) { | |
_harvest(allStrategies[i]); | |
} | |
@@ -298,12 +299,12 @@ contract VaultAdmin is VaultStorage { | |
/** | |
* @dev Collect reward tokens for a specific strategy and swap for supported | |
- * stablecoin via Uniswap | |
+ * stablecoin via Uniswap. Called from the vault. | |
* @param _strategyAddr Address of the strategy to collect rewards from | |
*/ | |
function harvest(address _strategyAddr) | |
external | |
- onlyVaultOrGovernor | |
+ onlyVaultOrGovernorOrStrategist | |
returns (uint256[] memory) | |
{ | |
return _harvest(_strategyAddr); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment