Euler diff: contracts/modules/EToken.sol

Before: contract 0x090c752B7b26d3cc382BF532eC9C4403C80D56CF
After: git 1d8c9f1d548570a0235cda39b13a76e658ae37d3
Files changed (6) hide show
  1. contracts/modules/EToken.sol +30 -0
  2. contracts/BaseModule.sol +3 -11
  3. contracts/Interfaces.sol +6 -0
  4. contracts/IRiskManager.sol +5 -5
  5. contracts/Base.sol +7 -0
  6. contracts/Constants.sol +3 -1
contracts/modules/EToken.sol CHANGED
@@ -94,8 +94,29 @@
94
94
  return balanceToUnderlyingAmount(assetCache, assetCache.reserveBalance) / assetCache.underlyingDecimalsScaler;
95
95
  }
96
96
 
97
97
 
98
+ /// @notice Convert an eToken balance to an underlying amount, taking into account current exchange rate
99
+ /// @param balance eToken balance, in internal book-keeping units (18 decimals)
100
+ /// @return Amount in underlying units, (same decimals as underlying token)
101
+ function convertBalanceToUnderlying(uint balance) external view returns (uint) {
102
+ (address underlying, AssetStorage storage assetStorage,,) = CALLER();
103
+ AssetCache memory assetCache = loadAssetCacheRO(underlying, assetStorage);
104
+
105
+ return balanceToUnderlyingAmount(assetCache, balance) / assetCache.underlyingDecimalsScaler;
106
+ }
107
+
108
+ /// @notice Convert an underlying amount to an eToken balance, taking into account current exchange rate
109
+ /// @param underlyingAmount Amount in underlying units (same decimals as underlying token)
110
+ /// @return eToken balance, in internal book-keeping units (18 decimals)
111
+ function convertUnderlyingToBalance(uint underlyingAmount) external view returns (uint) {
112
+ (address underlying, AssetStorage storage assetStorage,,) = CALLER();
113
+ AssetCache memory assetCache = loadAssetCacheRO(underlying, assetStorage);
114
+
115
+ return underlyingAmountToBalance(assetCache, decodeExternalAmount(assetCache, underlyingAmount));
116
+ }
117
+
118
+
98
119
  /// @notice Updates interest accumulator and totalBorrows, credits reserves, re-targets interest rate, and logs asset status
99
120
  function touch() external nonReentrant {
100
121
  (address underlying, AssetStorage storage assetStorage,,) = CALLER();
101
122
  AssetCache memory assetCache = loadAssetCache(underlying, assetStorage);
@@ -275,8 +296,17 @@
275
296
  function transfer(address to, uint amount) external returns (bool) {
276
297
  return transferFrom(address(0), to, amount);
277
298
  }
278
299
 
300
+ /// @notice Transfer the full eToken balance of an address to another
301
+ /// @param from This address must've approved the to address, or be a sub-account of msg.sender
302
+ /// @param to Xor with the desired sub-account ID (if applicable)
303
+ function transferFromMax(address from, address to) external returns (bool) {
304
+ (, AssetStorage storage assetStorage,,) = CALLER();
305
+
306
+ return transferFrom(from, to, assetStorage.users[from].balance);
307
+ }
308
+
279
309
  /// @notice Transfer eTokens from one address to another
280
310
  /// @param from This address must've approved the to address, or be a sub-account of msg.sender
281
311
  /// @param to Xor with the desired sub-account ID (if applicable)
282
312
  /// @param amount In internal book-keeping units (as returned from balanceOf).
contracts/BaseModule.sol CHANGED
@@ -22,24 +22,16 @@
22
22
  // Accessing parameters
23
23
 
24
24
  function unpackTrailingParamMsgSender() internal pure returns (address msgSender) {
25
25
  assembly {
26
- mstore(0, 0)
27
-
28
- calldatacopy(12, sub(calldatasize(), 40), 20)
29
- msgSender := mload(0)
26
+ msgSender := shr(96, calldataload(sub(calldatasize(), 40)))
30
27
  }
31
28
  }
32
29
 
33
30
  function unpackTrailingParams() internal pure returns (address msgSender, address proxyAddr) {
34
31
  assembly {
35
- mstore(0, 0)
36
-
37
- calldatacopy(12, sub(calldatasize(), 40), 20)
38
- msgSender := mload(0)
39
-
40
- calldatacopy(12, sub(calldatasize(), 20), 20)
41
- proxyAddr := mload(0)
32
+ msgSender := shr(96, calldataload(sub(calldatasize(), 40)))
33
+ proxyAddr := shr(96, calldataload(sub(calldatasize(), 20)))
42
34
  }
43
35
  }
44
36
 
45
37
 
contracts/Interfaces.sol CHANGED
@@ -18,8 +18,14 @@
18
18
  function transfer(address to, uint value) external returns (bool);
19
19
  function transferFrom(address from, address to, uint value) external returns (bool);
20
20
  }
21
21
 
22
+ interface IERC20Permit {
23
+ function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
24
+ function permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) external;
25
+ function permit(address owner, address spender, uint value, uint deadline, bytes calldata signature) external;
26
+ }
27
+
22
28
  interface IERC3156FlashBorrower {
23
29
  function onFlashLoan(address initiator, address token, uint256 amount, uint256 fee, bytes calldata data) external returns (bytes32);
24
30
  }
25
31
 
contracts/IRiskManager.sol CHANGED
@@ -27,11 +27,11 @@
27
27
  }
28
28
 
29
29
  function getNewMarketParameters(address underlying) external returns (NewMarketParameters memory);
30
30
 
31
- function requireLiquidity(address account) external;
32
- function computeLiquidity(address account) external returns (LiquidityStatus memory status);
33
- function computeAssetLiquidities(address account) external returns (AssetLiquidity[] memory assets);
31
+ function requireLiquidity(address account) external view;
32
+ function computeLiquidity(address account) external view returns (LiquidityStatus memory status);
33
+ function computeAssetLiquidities(address account) external view returns (AssetLiquidity[] memory assets);
34
34
 
35
- function getPrice(address underlying) external returns (uint twap, uint twapPeriod);
36
- function getPriceFull(address underlying) external returns (uint twap, uint twapPeriod, uint currPrice);
35
+ function getPrice(address underlying) external view returns (uint twap, uint twapPeriod);
36
+ function getPriceFull(address underlying) external view returns (uint twap, uint twapPeriod, uint currPrice);
37
37
  }
contracts/Base.sol CHANGED
@@ -52,8 +52,15 @@
52
52
  modifier reentrantOK() { // documentation only
53
53
  _;
54
54
  }
55
55
 
56
+ // Used to flag functions which do not modify storage, but do perform a delegate call
57
+ // to a view function, which prohibits a standard view modifier. The flag is used to
58
+ // patch state mutability in compiled ABIs and interfaces.
59
+ modifier staticDelegate() {
60
+ _;
61
+ }
62
+
56
63
  // WARNING: Must be very careful with this modifier. It resets the free memory pointer
57
64
  // to the value it was when the function started. This saves gas if more memory will
58
65
  // be allocated in the future. However, if the memory will be later referenced
59
66
  // (for example because the function has returned a pointer to it) then you cannot
contracts/Constants.sol CHANGED
@@ -20,11 +20,12 @@
20
20
  uint internal constant RESERVE_FEE_SCALE = 4_000_000_000; // must fit into a uint32
21
21
  uint32 internal constant DEFAULT_RESERVE_FEE = uint32(0.23 * 4_000_000_000);
22
22
  uint internal constant INITIAL_INTEREST_ACCUMULATOR = 1e27;
23
23
  uint internal constant AVERAGE_LIQUIDITY_PERIOD = 24 * 60 * 60;
24
- uint16 internal constant MIN_UNISWAP3_OBSERVATION_CARDINALITY = 10;
24
+ uint16 internal constant MIN_UNISWAP3_OBSERVATION_CARDINALITY = 144;
25
25
  uint24 internal constant DEFAULT_TWAP_WINDOW_SECONDS = 30 * 60;
26
26
  uint32 internal constant DEFAULT_BORROW_FACTOR = uint32(0.28 * 4_000_000_000);
27
+ uint32 internal constant SELF_COLLATERAL_FACTOR = uint32(0.95 * 4_000_000_000);
27
28
 
28
29
 
29
30
  // Implementation internals
30
31
 
@@ -74,8 +75,9 @@
74
75
  // Classes
75
76
  uint internal constant MODULEID__IRM_CLASS__STABLE = 2_000_500;
76
77
  uint internal constant MODULEID__IRM_CLASS__MAJOR = 2_000_501;
77
78
  uint internal constant MODULEID__IRM_CLASS__MIDCAP = 2_000_502;
79
+ uint internal constant MODULEID__IRM_CLASS__MEGA = 2_000_503;
78
80
 
79
81
  // Swap types
80
82
  uint internal constant SWAP_TYPE__UNI_EXACT_INPUT_SINGLE = 1;
81
83
  uint internal constant SWAP_TYPE__UNI_EXACT_INPUT = 2;