diff --git a/CHANGELOG.md b/CHANGELOG.md index eab8586b6..efaee898c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,8 +18,6 @@ This release implements a global lock on `Main` (by inherinting from `GlobalReen This release prepares the core protocol for veRSR through the introduction of 3 registries (`DAOFeeRegistry`, `AssetPluginRegistry`, and `VersionRegistry`) and through restricting component upgrades to be handled by `Main`, where upgrade constraints can be enforced. -RTokenAsset.price() now reverts if the RTokenAsset is unpriced. - The release also expands collateral decimal support from 18 to 21, with some caveats about minimum token value. See [docs/solidity-style.md](./docs/solidity-style.md#Collateral-decimals) for more details. Finally, it adds resistance to toxic issuance by charging more when the collateral is under peg. diff --git a/contracts/facade/facets/ActFacet.sol b/contracts/facade/facets/ActFacet.sol index d2781d085..61f3efcc5 100644 --- a/contracts/facade/facets/ActFacet.sol +++ b/contracts/facade/facets/ActFacet.sol @@ -114,23 +114,19 @@ contract ActFacet is Multicall { } surpluses[i] = erc20s[i].balanceOf(address(revenueTrader)); + (uint192 low, ) = reg.assets[i].price(); // {UoA/tok} + if (low == 0) continue; - try reg.assets[i].price() returns (uint192 low, uint192) { - if (low == 0) continue; - - // {qTok} = {UoA} / {UoA/tok} - minTradeAmounts[i] = minTradeVolume.safeDiv(low, FLOOR).shiftl_toUint( - int8(reg.assets[i].erc20Decimals()) - ); + // {qTok} = {UoA} / {UoA/tok} + minTradeAmounts[i] = minTradeVolume.safeDiv(low, FLOOR).shiftl_toUint( + int8(reg.assets[i].erc20Decimals()) + ); - if ( - surpluses[i] > minTradeAmounts[i] && - revenueTrader.trades(erc20s[i]) == ITrade(address(0)) - ) { - canStart[i] = true; - } - } catch { - continue; + if ( + surpluses[i] > minTradeAmounts[i] && + revenueTrader.trades(erc20s[i]) == ITrade(address(0)) + ) { + canStart[i] = true; } } diff --git a/contracts/interfaces/IAsset.sol b/contracts/interfaces/IAsset.sol index 8e3a0fd5a..1543b2c78 100644 --- a/contracts/interfaces/IAsset.sol +++ b/contracts/interfaces/IAsset.sol @@ -26,7 +26,7 @@ interface IAsset is IRewardable { /// @dev Called immediately after deployment, before use function refresh() external; - /// Should not revert (RTokenAsset exempt) + /// Should not revert /// low should be nonzero if the asset could be worth selling /// @return low {UoA/tok} The lower end of the price estimate /// @return high {UoA/tok} The upper end of the price estimate diff --git a/contracts/p1/RevenueTrader.sol b/contracts/p1/RevenueTrader.sol index 8dd55578e..a0ddd08b8 100644 --- a/contracts/p1/RevenueTrader.sol +++ b/contracts/p1/RevenueTrader.sol @@ -99,7 +99,6 @@ contract RevenueTraderP1 is TradingP1, IRevenueTrader { /// Process some number of tokens /// If the tokenToBuy is included in erc20s, RevenueTrader will distribute it at end of the tx - /// @dev If tokenToBuy is the RToken revenue processing halts if RTokenAsset.price() reverts /// @param erc20s The ERC20s to manage; can be tokenToBuy or anything registered /// @param kinds The kinds of auctions to launch: DUTCH_AUCTION | BATCH_AUCTION /// @custom:interaction not strictly RCEI; nonReentrant diff --git a/contracts/plugins/assets/RTokenAsset.sol b/contracts/plugins/assets/RTokenAsset.sol index c6e2f0b2c..938032cf0 100644 --- a/contracts/plugins/assets/RTokenAsset.sol +++ b/contracts/plugins/assets/RTokenAsset.sol @@ -62,7 +62,7 @@ contract RTokenAsset is IAsset, VersionedAsset, IRTokenOracle { /// in lending markets or anywhere where secondary market price is the central concern. /// @return low {UoA/tok} The low price estimate /// @return high {UoA/tok} The high price estimate - function tryPrice() public view virtual returns (uint192 low, uint192 high) { + function tryPrice() external view virtual returns (uint192 low, uint192 high) { (uint192 lowBUPrice, uint192 highBUPrice) = basketHandler.price(true); // {UoA/BU} require(lowBUPrice != 0 && highBUPrice != FIX_MAX, "invalid price"); assert(lowBUPrice <= highBUPrice); // not obviously true just by inspection @@ -98,7 +98,13 @@ contract RTokenAsset is IAsset, VersionedAsset, IRTokenOracle { /// @return {UoA/tok} The lower end of the price estimate /// @return {UoA/tok} The upper end of the price estimate function price() public view virtual returns (uint192, uint192) { - return tryPrice(); + try this.tryPrice() returns (uint192 low, uint192 high) { + return (low, high); + } catch (bytes memory errData) { + // see: docs/solidity-style.md#Catching-Empty-Data + if (errData.length == 0) revert(); // solhint-disable-line reason-string + return (0, FIX_MAX); + } } /// Should not revert @@ -107,7 +113,7 @@ contract RTokenAsset is IAsset, VersionedAsset, IRTokenOracle { /// @return lotLow {UoA/tok} The lower end of the lot price estimate /// @return lotHigh {UoA/tok} The upper end of the lot price estimate function lotPrice() external view virtual returns (uint192 lotLow, uint192 lotHigh) { - return tryPrice(); + return price(); } /// @return {tok} The balance of the ERC20 in whole tokens diff --git a/contracts/plugins/assets/curve/CurveRecursiveCollateral.sol b/contracts/plugins/assets/curve/CurveRecursiveCollateral.sol index 4094f953d..64accb7f2 100644 --- a/contracts/plugins/assets/curve/CurveRecursiveCollateral.sol +++ b/contracts/plugins/assets/curve/CurveRecursiveCollateral.sol @@ -14,8 +14,6 @@ import "../OracleLib.sol"; * @notice Collateral plugin for a CurveLP token for a pool between a * a USD reference token and a USD RToken. * - * @notice DEPRECATED - * * Note: * - The RToken _must_ be the same RToken using this plugin as collateral! * - The RToken SHOULD have an RSR overcollateralization layer. DO NOT USE WITHOUT RSR! diff --git a/contracts/plugins/assets/curve/CurveStableMetapoolCollateral.sol b/contracts/plugins/assets/curve/CurveStableMetapoolCollateral.sol index 00665b978..6b958675e 100644 --- a/contracts/plugins/assets/curve/CurveStableMetapoolCollateral.sol +++ b/contracts/plugins/assets/curve/CurveStableMetapoolCollateral.sol @@ -10,9 +10,6 @@ interface ICurveMetaPool is ICurvePool, IERC20Metadata { /** * @title CurveStableMetapoolCollateral - * - * @notice DEPRECATED in 4.0.0 - * * This plugin contract is intended for 2-fiattoken stable metapools that * DO NOT involve RTokens, such as LUSD-fraxBP or MIM-3CRV. * diff --git a/contracts/plugins/assets/curve/CurveStableRTokenMetapoolCollateral.sol b/contracts/plugins/assets/curve/CurveStableRTokenMetapoolCollateral.sol index 5cdd6e80a..50eab5bcd 100644 --- a/contracts/plugins/assets/curve/CurveStableRTokenMetapoolCollateral.sol +++ b/contracts/plugins/assets/curve/CurveStableRTokenMetapoolCollateral.sol @@ -8,8 +8,6 @@ import "./CurveStableMetapoolCollateral.sol"; * This plugin contract is intended for 2-fiattoken stable metapools that * involve RTokens, such as eUSD-fraxBP. * - * @notice DEPRECATED in 4.0.0 - * * tok = ConvexStakingWrapper(pairedUSDRToken/USDBasePool) * ref = PairedUSDRToken/USDBasePool pool invariant * tar = USD @@ -144,7 +142,6 @@ contract CurveStableRTokenMetapoolCollateral is CurveStableMetapoolCollateral { override returns (uint192 lowPaired, uint192 highPaired) { - // can revert if pairedToken is a >=4.0.0 RToken return pairedAssetRegistry.toAsset(pairedToken).price(); } } diff --git a/contracts/spells/4_2_0.sol b/contracts/spells/4_2_0.sol index 29d34a6e5..4e6416acc 100644 --- a/contracts/spells/4_2_0.sol +++ b/contracts/spells/4_2_0.sol @@ -172,7 +172,7 @@ contract Upgrade4_2_0 is Versioned { if (_mainnet) { // 4.2.0 deployer (mainnet) - deployer = IDeployer(0x40cd76E78Af4aAc744D1FA443359e7e26c982F9D); + deployer = IDeployer(0x08638a2efE63d3A4E5056860E4292B6C059D3BaD); // DAO registries (mainnet) registries = IDeployer.Registries( @@ -195,7 +195,7 @@ contract Upgrade4_2_0 is Versioned { } } else { // 4.2.0 deployer (base) - deployer = IDeployer(0x9FF9c353136e86EFe02ADD177E7c9769f8a5A77F); + deployer = IDeployer(0x5574eD38ceAFB537b274E3562414DCA057d8Ff41); // DAO registries (base) registries = IDeployer.Registries( diff --git a/docs/collateral.md b/docs/collateral.md index 4ed8080e0..03854303c 100644 --- a/docs/collateral.md +++ b/docs/collateral.md @@ -41,7 +41,7 @@ interface IAsset is IRewardable { /// @dev Called immediately after deployment, before use function refresh() external; - /// Should not revert (RTokenAsset exempt) + /// Should not revert /// low should be nonzero if the asset could be worth selling /// @return low {UoA/tok} The lower end of the price estimate /// @return high {UoA/tok} The upper end of the price estimate diff --git a/docs/overview.md b/docs/overview.md index 242a0d3c9..6b1d231e9 100644 --- a/docs/overview.md +++ b/docs/overview.md @@ -58,8 +58,6 @@ The protocol requires an asset in order to handle an ERC20. Some assets are `col Pure assets provide USD pricing information only. -All assets are expected to have non-reverting `price()` functions, with the exception of RTokenAsset. The consequence of `RTokenAsset.price()` reverting is to halt most forms of revenue trading but allow other functionality to continue. - #### Collateral The more interesting type of asset is a _collateral_ asset. A collateral asset provides additional `refPerTok` and `targetPerRef` exchange rates that allow revenue to be measured against some external unit, called the "target unit". These contracts maintain an overall `status() view returns (CollateralStatus)` enum that the BasketHandler uses to define an overall notion of basket status. If the collateral ever becomes DISABLED, the BasketHandler will swap it out for a SOUND collateral in the appropriate quantity. diff --git a/scripts/addresses/1-tmp-deployments.json b/scripts/addresses/1-tmp-deployments.json index fee6e2a91..f88b7008a 100644 --- a/scripts/addresses/1-tmp-deployments.json +++ b/scripts/addresses/1-tmp-deployments.json @@ -6,17 +6,17 @@ "tradingLib": "0xD595456AC36aab96CF9d10d1ADF8C3b4576C7937", "facade": "0x9d49b363d492725412bf8350bBb525B7a80a7470", "facets": { - "actFacet": "0x8578538EB08B39f3aE363757B30afB5a12DDcF0c", + "actFacet": "0xCa60954E8819827B0C56e1ec313175fE68712d98", "readFacet": "0x823110a13eB26cB09c4Bb118DBfE4ff5f96D5526", "maxIssuableFacet": "0x5771d976696AA180Fed276FB6571fE2f41D0b849", "backingBufferFacet": "0xB555921a031D321687aE8B0569dA7B6da8BCB209", "revenueFacet": "0x69c21f4828c57D3BB5Eb5fEEa6C5c1432e193510", "tradeHelperFacet": "0x9c09e506e00ac87E2413b7501702fAcA690201Fb" }, - "facadeWriteLib": "0x99268AD5808BDFC64aE4C8d95dd8b61b1bef32Bb", + "facadeWriteLib": "0xe4DB7DA0b89365A6eD954594638D21Fb19661EB6", "basketLib": "0x2fdD94F363644FEDE5106B22b1706E45D4dD9bea", - "facadeWrite": "0xe18131bd99127b6601c4A78dB25fF963006060e2", - "deployer": "0x40cd76E78Af4aAc744D1FA443359e7e26c982F9D", + "facadeWrite": "0x46CF884c423e35947b27440fc0Bc77d968C74F49", + "deployer": "0x08638a2efE63d3A4E5056860E4292B6C059D3BaD", "rsrAsset": "0xbCb71eE9c3372f3444cBBe3E1b263204967EdBE3", "implementations": { "main": "0xc5bf686CfB85786fcFfF557297D4afF8F4e15e44", @@ -25,7 +25,7 @@ "dutchTrade": "0xCC3Cb888dEA5948bbEB7747Aed31128b71b7689D" }, "components": { - "assetRegistry": "0x1aCfF3eB9E4250Fb75526ceb3ff3b05c0CCfa42D", + "assetRegistry": "0xcB7e10000De0DAcE5A79c620191Cab2517693637", "backingManager": "0xc501c9074CE15A4B00dd0B51B3c372518e6D3BA2", "basketHandler": "0x54A8fa5217970e2040590DDD7c16f72B1fb57a3C", "broker": "0x63c61086418406eBB062c5C6dF80F46c6d052d4c", diff --git a/scripts/addresses/8453-tmp-deployments.json b/scripts/addresses/8453-tmp-deployments.json index 5e0cf41a1..f45da9937 100644 --- a/scripts/addresses/8453-tmp-deployments.json +++ b/scripts/addresses/8453-tmp-deployments.json @@ -6,17 +6,17 @@ "tradingLib": "0x0E6D6cBdA4629Fb2D82b4b4Af0D5c887f21F3BC7", "facade": "0xE41416d8dC94ac1F6d12282d6D46B714F39a87d9", "facets": { - "actFacet": "0xAdfB9BCdA981136c83076a52Ef8fE4D8B2b520e7", + "actFacet": "0x72Be467048a4D9CbcC599251243f3eD9F46a42f5", "readFacet": "0x5Af543D6F95a98200Dd770f39A902Fe793BAeB27", "maxIssuableFacet": "0x63FDcB1E8Ee5C4B64A5c4ce0FB97597917920cb6", "backingBufferFacet": "0x38c7e9427960E427f6c84b3A096021f47a9Afb82", "revenueFacet": "0x4c2FCA94163355a5B81F4D924Bce8cCbACc15406", "tradeHelperFacet": "0xC1E16AD7844Da1AEFFa6c3932AD02b823DE12d3F" }, - "facadeWriteLib": "0xc9291eF2f81dBc9B412381aBe83b28954220565E", + "facadeWriteLib": "0x79190AD7Bb1aE9C25F3Fe7aBCfCEce52a8f34A0a", "basketLib": "0x3700b22C742980be9D22740933d4a041A64f7314", - "facadeWrite": "0xCBE084C44e7A2223F76362Dcc4EbDacA5Fb1cbA7", - "deployer": "0x9FF9c353136e86EFe02ADD177E7c9769f8a5A77F", + "facadeWrite": "0x5Fb4E33e7952ED4b1dc6C08966D797c61BBFF021", + "deployer": "0x5574eD38ceAFB537b274E3562414DCA057d8Ff41", "rsrAsset": "0x22018D85BFdA9e2673FB4101e957562a1e952Cdf", "implementations": { "main": "0x6D05CB2CB647B58189FA16f81784C05B4bcd4fe9", @@ -25,7 +25,7 @@ "dutchTrade": "0x8A9F74d40c5323E73B63a80c4282658fD43F3AA2" }, "components": { - "assetRegistry": "0x63be601cDE1121C987B885cc319b44e0a9d707a2", + "assetRegistry": "0xaBd7E7a5C846eD497681a590feBED99e7157B6a3", "backingManager": "0xF73EB45d83AC86f8a6F75a6252ca1a59a9A3aED3", "basketHandler": "0x5c83CA710E72D130E3B74aEC5b739676ef5737c2", "broker": "0x714341800AD1913B5FCCBFd5d136553Ad1C314d6", diff --git a/scripts/addresses/base-4.2.0/8453-tmp-deployments.json b/scripts/addresses/base-4.2.0/8453-tmp-deployments.json index 5e0cf41a1..275c298b3 100644 --- a/scripts/addresses/base-4.2.0/8453-tmp-deployments.json +++ b/scripts/addresses/base-4.2.0/8453-tmp-deployments.json @@ -6,17 +6,17 @@ "tradingLib": "0x0E6D6cBdA4629Fb2D82b4b4Af0D5c887f21F3BC7", "facade": "0xE41416d8dC94ac1F6d12282d6D46B714F39a87d9", "facets": { - "actFacet": "0xAdfB9BCdA981136c83076a52Ef8fE4D8B2b520e7", + "actFacet": "0x72Be467048a4D9CbcC599251243f3eD9F46a42f5", "readFacet": "0x5Af543D6F95a98200Dd770f39A902Fe793BAeB27", "maxIssuableFacet": "0x63FDcB1E8Ee5C4B64A5c4ce0FB97597917920cb6", "backingBufferFacet": "0x38c7e9427960E427f6c84b3A096021f47a9Afb82", "revenueFacet": "0x4c2FCA94163355a5B81F4D924Bce8cCbACc15406", "tradeHelperFacet": "0xC1E16AD7844Da1AEFFa6c3932AD02b823DE12d3F" }, - "facadeWriteLib": "0xc9291eF2f81dBc9B412381aBe83b28954220565E", + "facadeWriteLib": "0x79190AD7Bb1aE9C25F3Fe7aBCfCEce52a8f34A0a", "basketLib": "0x3700b22C742980be9D22740933d4a041A64f7314", - "facadeWrite": "0xCBE084C44e7A2223F76362Dcc4EbDacA5Fb1cbA7", - "deployer": "0x9FF9c353136e86EFe02ADD177E7c9769f8a5A77F", + "facadeWrite": "0x5Fb4E33e7952ED4b1dc6C08966D797c61BBFF021", + "deployer": "0x5574eD38ceAFB537b274E3562414DCA057d8Ff41", "rsrAsset": "0x22018D85BFdA9e2673FB4101e957562a1e952Cdf", "implementations": { "main": "0x6D05CB2CB647B58189FA16f81784C05B4bcd4fe9", @@ -25,7 +25,7 @@ "dutchTrade": "0x8A9F74d40c5323E73B63a80c4282658fD43F3AA2" }, "components": { - "assetRegistry": "0x63be601cDE1121C987B885cc319b44e0a9d707a2", + "assetRegistry": "0xaBd7E7a5C846eD497681a590feBED99e7157B6a3", "backingManager": "0xF73EB45d83AC86f8a6F75a6252ca1a59a9A3aED3", "basketHandler": "0x5c83CA710E72D130E3B74aEC5b739676ef5737c2", "broker": "0x714341800AD1913B5FCCBFd5d136553Ad1C314d6", @@ -37,4 +37,4 @@ "stRSR": "0xb3dCcEf35647A8821C76f796bE8B5426Cc953412" } } -} \ No newline at end of file +} diff --git a/scripts/addresses/mainnet-4.2.0/1-tmp-deployments.json b/scripts/addresses/mainnet-4.2.0/1-tmp-deployments.json index fee6e2a91..c77f710d0 100644 --- a/scripts/addresses/mainnet-4.2.0/1-tmp-deployments.json +++ b/scripts/addresses/mainnet-4.2.0/1-tmp-deployments.json @@ -6,17 +6,17 @@ "tradingLib": "0xD595456AC36aab96CF9d10d1ADF8C3b4576C7937", "facade": "0x9d49b363d492725412bf8350bBb525B7a80a7470", "facets": { - "actFacet": "0x8578538EB08B39f3aE363757B30afB5a12DDcF0c", + "actFacet": "0xCa60954E8819827B0C56e1ec313175fE68712d98", "readFacet": "0x823110a13eB26cB09c4Bb118DBfE4ff5f96D5526", "maxIssuableFacet": "0x5771d976696AA180Fed276FB6571fE2f41D0b849", "backingBufferFacet": "0xB555921a031D321687aE8B0569dA7B6da8BCB209", "revenueFacet": "0x69c21f4828c57D3BB5Eb5fEEa6C5c1432e193510", "tradeHelperFacet": "0x9c09e506e00ac87E2413b7501702fAcA690201Fb" }, - "facadeWriteLib": "0x99268AD5808BDFC64aE4C8d95dd8b61b1bef32Bb", + "facadeWriteLib": "0xe4DB7DA0b89365A6eD954594638D21Fb19661EB6", "basketLib": "0x2fdD94F363644FEDE5106B22b1706E45D4dD9bea", - "facadeWrite": "0xe18131bd99127b6601c4A78dB25fF963006060e2", - "deployer": "0x40cd76E78Af4aAc744D1FA443359e7e26c982F9D", + "facadeWrite": "0x46CF884c423e35947b27440fc0Bc77d968C74F49", + "deployer": "0x08638a2efE63d3A4E5056860E4292B6C059D3BaD", "rsrAsset": "0xbCb71eE9c3372f3444cBBe3E1b263204967EdBE3", "implementations": { "main": "0xc5bf686CfB85786fcFfF557297D4afF8F4e15e44", @@ -25,7 +25,7 @@ "dutchTrade": "0xCC3Cb888dEA5948bbEB7747Aed31128b71b7689D" }, "components": { - "assetRegistry": "0x1aCfF3eB9E4250Fb75526ceb3ff3b05c0CCfa42D", + "assetRegistry": "0xcB7e10000De0DAcE5A79c620191Cab2517693637", "backingManager": "0xc501c9074CE15A4B00dd0B51B3c372518e6D3BA2", "basketHandler": "0x54A8fa5217970e2040590DDD7c16f72B1fb57a3C", "broker": "0x63c61086418406eBB062c5C6dF80F46c6d052d4c", @@ -37,4 +37,4 @@ "stRSR": "0x8E594FFb702C48a9fF8ae56FAeC795D83A69B387" } } -} \ No newline at end of file +} diff --git a/scripts/deploy.ts b/scripts/deploy.ts index 9d475d193..da57079f5 100644 --- a/scripts/deploy.ts +++ b/scripts/deploy.ts @@ -72,6 +72,8 @@ async function main() { 'phase2-assets/collaterals/deploy_convex_paypool_collateral.ts', 'phase2-assets/collaterals/deploy_convex_crvusd_usdc_collateral.ts', 'phase2-assets/collaterals/deploy_convex_crvusd_usdt_collateral.ts', + 'phase2-assets/collaterals/deploy_convex_rToken_metapool_plugin.ts', + 'phase2-assets/collaterals/deploy_convex_ethplus_eth.ts', 'phase2-assets/collaterals/deploy_dsr_sdai.ts', 'phase2-assets/collaterals/deploy_cbeth_collateral.ts', 'phase2-assets/collaterals/deploy_morpho_aavev2_plugin.ts', diff --git a/scripts/deployment/phase2-assets/collaterals/deploy_convex_ethplus_eth.ts b/scripts/deployment/phase2-assets/collaterals/deploy_convex_ethplus_eth.ts index 47731072f..833ece0dc 100644 --- a/scripts/deployment/phase2-assets/collaterals/deploy_convex_ethplus_eth.ts +++ b/scripts/deployment/phase2-assets/collaterals/deploy_convex_ethplus_eth.ts @@ -28,7 +28,6 @@ import { } from '../../../../test/plugins/individual-collateral/curve/constants' // This file specifically deploys CurveAppreciatingRTokenSelfReferentialCollateral Plugin for ETH+/ETH -// DEPRECATED async function main() { // ==== Read Configuration ==== diff --git a/scripts/deployment/phase2-assets/collaterals/deploy_convex_rToken_metapool_plugin.ts b/scripts/deployment/phase2-assets/collaterals/deploy_convex_rToken_metapool_plugin.ts index 50373ab6b..e9fc511b4 100644 --- a/scripts/deployment/phase2-assets/collaterals/deploy_convex_rToken_metapool_plugin.ts +++ b/scripts/deployment/phase2-assets/collaterals/deploy_convex_rToken_metapool_plugin.ts @@ -33,7 +33,6 @@ import { } from '../../../../test/plugins/individual-collateral/curve/constants' // This file specifically deploys Convex RToken Metapool Plugin for eUSD/fraxBP -// DEPRECATED async function main() { // ==== Read Configuration ==== diff --git a/scripts/verify_etherscan.ts b/scripts/verify_etherscan.ts index 783fc5589..2b6832d61 100644 --- a/scripts/verify_etherscan.ts +++ b/scripts/verify_etherscan.ts @@ -90,7 +90,6 @@ async function main() { 'collateral-plugins/verify_aerodrome_usdc_eusd.ts', 'collateral-plugins/verify_aerodrome_weth_aero.ts', 'collateral-plugins/verify_aerodrome_mog_weth.ts', - 'collateral-plugins/verify_aerodrome_usdz_usdc.ts', 'collateral-plugins/verify_aerodrome_weth_cbbtc.ts', 'collateral-plugins/verify_aerodrome_weth_well.ts', 'collateral-plugins/verify_aerodrome_weth_degen.ts', diff --git a/test/Facade.test.ts b/test/Facade.test.ts index 83e2c0795..7f5f07353 100644 --- a/test/Facade.test.ts +++ b/test/Facade.test.ts @@ -717,14 +717,11 @@ describe('Facade + FacadeMonitor contracts', () => { expect(canStart[i]).to.equal(false) expect(surpluses[i]).to.equal(0) } - - if (erc20s[i] != rToken.address) { - const asset = await ethers.getContractAt('IAsset', await assetRegistry.toAsset(erc20s[i])) - const [low] = await asset.price() - expect(minTradeAmounts[i]).to.equal( - low.gt(0) ? minTradeVolume.mul(bn('10').pow(await asset.erc20Decimals())).div(low) : 0 - ) // 1% oracleError - } + const asset = await ethers.getContractAt('IAsset', await assetRegistry.toAsset(erc20s[i])) + const [low] = await asset.price() + expect(minTradeAmounts[i]).to.equal( + low.gt(0) ? minTradeVolume.mul(bn('10').pow(await asset.erc20Decimals())).div(low) : 0 + ) // 1% oracleError } // Run revenue auctions via multicall diff --git a/test/Recollateralization.test.ts b/test/Recollateralization.test.ts index 01c32f89d..023ab8406 100644 --- a/test/Recollateralization.test.ts +++ b/test/Recollateralization.test.ts @@ -56,7 +56,7 @@ import { import snapshotGasCost from './utils/snapshotGasCost' import { expectTrade, getTrade, dutchBuyAmount } from './utils/trades' import { withinTolerance } from './utils/matchers' -import { expectRTokenPrice, setOraclePrice } from './utils/oracles' +import { expectRTokenPrice, expectUnpriced, setOraclePrice } from './utils/oracles' import { useEnv } from '#/utils/env' import { mintCollaterals } from './utils/tokens' @@ -1033,8 +1033,8 @@ describe(`Recollateralization - P${IMPLEMENTATION}`, () => { expect(await token0.balanceOf(backingManager.address)).to.equal(issueAmount) expect(await token1.balanceOf(backingManager.address)).to.equal(0) - // RTokenAsset.price() should revert - await expect(rTokenAsset.price()).to.be.revertedWith('invalid price') + // RToken unpriced + await expectUnpriced(rTokenAsset.address) // Attempt to recollateralize (no assets to sell) await expect(facadeTest.runAuctionsForAllTraders(rToken.address)).to.not.emit( @@ -1045,7 +1045,7 @@ describe(`Recollateralization - P${IMPLEMENTATION}`, () => { // Nothing changes until situation is resolved expect(await basketHandler.status()).to.equal(CollateralStatus.SOUND) expect(await basketHandler.fullyCollateralized()).to.equal(false) - await expect(rTokenAsset.price()).to.be.revertedWith('invalid price') + await expectUnpriced(rTokenAsset.address) }) context('Should successfully recollateralize after governance basket switch', () => { diff --git a/test/Revenues.test.ts b/test/Revenues.test.ts index dc929e163..95ece509c 100644 --- a/test/Revenues.test.ts +++ b/test/Revenues.test.ts @@ -636,18 +636,18 @@ describe(`Revenues - P${IMPLEMENTATION}`, () => { expect(await rsr.balanceOf(rTokenTrader.address)).to.equal(0) }) - it('Should not launch revenue auction if RTokenAsset.price() reverts', async () => { + it('Should launch revenue auction if UNPRICED', async () => { // After oracleTimeout it should still launch auction for RToken await advanceTime(DECAY_DELAY.toString()) await rsr.connect(addr1).transfer(rTokenTrader.address, issueAmount) await rTokenTrader.callStatic.manageTokens([rsr.address], [TradeKind.BATCH_AUCTION]) - // After priceTimeout it should not buy RToken anymore + // After priceTimeout it should not buy RToken await advanceTime(PRICE_TIMEOUT.toString()) await rsr.connect(addr1).transfer(rTokenTrader.address, issueAmount) await expect( rTokenTrader.manageTokens([rsr.address], [TradeKind.BATCH_AUCTION]) - ).to.be.revertedWith('invalid price') + ).to.be.revertedWith('buy asset price unknown') }) it('Should not launch revenue auction if 0 erc20s len', async () => { diff --git a/test/plugins/Asset.test.ts b/test/plugins/Asset.test.ts index 02fa4fc40..a80609c73 100644 --- a/test/plugins/Asset.test.ts +++ b/test/plugins/Asset.test.ts @@ -308,13 +308,11 @@ describe('Assets contracts #fast', () => { await setOraclePrice(collateral0.address, bn('0')) await setOraclePrice(collateral1.address, bn('0')) - // Should be unpriced now (except RTokenAsset) + // Should be unpriced now await expectUnpriced(rsrAsset.address) await expectUnpriced(compAsset.address) await expectUnpriced(aaveAsset.address) - - // RTokenAsset.price() should revert instead - await expect(rTokenAsset.price()).to.be.revertedWith('invalid price') + await expectUnpriced(rTokenAsset.address) }) it('Should return 0 price for RTokenAsset in full haircut scenario', async () => { @@ -449,15 +447,15 @@ describe('Assets contracts #fast', () => { await invalidFiatCollateral.setSimplyRevert(true) await expect(invalidFiatCollateral.price()).to.be.revertedWith('errormsg') - // RTokenAsset.price() should pass through the same error for its revert - await expect(rTokenAsset.price()).to.be.revertedWith('errormsg') + // Check RToken unpriced + await expectUnpriced(rTokenAsset.address) // Runnning out of gas await invalidFiatCollateral.setSimplyRevert(false) await expect(invalidFiatCollateral.price()).to.be.reverted - // RTokenAsset.price() should revert with OOG - await expect(rTokenAsset.price()).to.be.revertedWithoutReason + // Check RToken price reverts + await expect(rTokenAsset.price()).to.be.reverted }) it('Should return latestPrice() for RTokenAsset correctly', async () => { @@ -526,7 +524,6 @@ describe('Assets contracts #fast', () => { it('Regression test -- Should handle unpriced collateral for RTokenAsset', async () => { // https://github.com/code-423n4/2023-07-reserve-findings/issues/20 - // change in behavior on 11/12/2025: now should revert instead of being unpriced // Swap one of the collaterals for an invalid one const InvalidFiatCollateralFactory = await ethers.getContractFactory('InvalidFiatCollateral') @@ -550,8 +547,8 @@ describe('Assets contracts #fast', () => { // Set unpriced collateral await invalidFiatCollateral.setUnpriced(true) - // Check RTokenAsset.price() reverts - await expect(rTokenAsset.price()).to.be.revertedWith('invalid price') + // Check RToken is unpriced + await expectUnpriced(rTokenAsset.address) // Oracle price update should revert await expect(rTokenAsset.forceUpdatePrice()).to.be.revertedWith('invalid price')