Skip to content
This repository has been archived by the owner on May 24, 2024. It is now read-only.

Commit

Permalink
make view methods that loadAssetCacheRO check the re-entrancy guard i…
Browse files Browse the repository at this point in the history
…s unlocked

- This is in case external code is executed during (for example) a swap, this external
  code cannot see temporarily inconsistent states
  • Loading branch information
hoytech committed Aug 3, 2022
1 parent bb7ef7a commit 91adeee
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 2 deletions.
5 changes: 5 additions & 0 deletions contracts/BaseLogic.sol
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,11 @@ abstract contract BaseLogic is BaseModule {
}

function loadAssetCacheRO(address underlying, AssetStorage storage assetStorage) internal view returns (AssetCache memory assetCache) {
require(reentrancyLock == REENTRANCYLOCK__UNLOCKED, "e/ro-reentrancy");
initAssetCache(underlying, assetStorage, assetCache);
}

function internalLoadAssetCacheRO(address underlying, AssetStorage storage assetStorage) internal view returns (AssetCache memory assetCache) {
initAssetCache(underlying, assetStorage, assetCache);
}

Expand Down
4 changes: 2 additions & 2 deletions contracts/modules/RiskManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ contract RiskManager is IRiskManager, BaseLogic {
function getPrice(address underlying) external view override returns (uint twap, uint twapPeriod) {
AssetConfig memory config = resolveAssetConfig(underlying);
AssetStorage storage assetStorage = eTokenLookup[config.eTokenAddress];
AssetCache memory assetCache = loadAssetCacheRO(underlying, assetStorage);
AssetCache memory assetCache = internalLoadAssetCacheRO(underlying, assetStorage);

(twap, twapPeriod) = getPriceInternal(assetCache, config);
}
Expand All @@ -229,7 +229,7 @@ contract RiskManager is IRiskManager, BaseLogic {
function getPriceFull(address underlying) external view override returns (uint twap, uint twapPeriod, uint currPrice) {
AssetConfig memory config = resolveAssetConfig(underlying);
AssetStorage storage assetStorage = eTokenLookup[config.eTokenAddress];
AssetCache memory assetCache = loadAssetCacheRO(underlying, assetStorage);
AssetCache memory assetCache = internalLoadAssetCacheRO(underlying, assetStorage);

(twap, twapPeriod) = getPriceInternal(assetCache, config);

Expand Down
15 changes: 15 additions & 0 deletions test/maliciousToken.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,21 @@ et.testSet({
})


.test({
desc: "deposit - transfer from reenters view method",
actions: ctx => [
{ send: 'tokens.TST.configure', args: ['transfer-from/call', et.abiEncode(
['address', 'bytes'],
[
ctx.contracts.eTokens.eTST.address,
ctx.contracts.eTokens.eTST.interface.encodeFunctionData('balanceOfUnderlying', [ctx.wallet.address]),
]
)]},
{ send: 'eTokens.eTST.deposit', args: [0, et.eth(1)], expectError: 'e/ro-reentrancy', },
],
})


.test({
desc: "withdraw - underflow",
actions: ctx => [
Expand Down

0 comments on commit 91adeee

Please sign in to comment.