From db0b95aba14c0240ab5d96fdf42863abf99d42b7 Mon Sep 17 00:00:00 2001 From: Nicholas Addison Date: Wed, 9 Oct 2024 15:59:49 +1100 Subject: [PATCH] Allow the cross price to be 20 basis points below 1 --- src/contracts/AbstractARM.sol | 17 +++++++++++++---- .../fork/LidoFixedPriceMultiLpARM/Setters.t.sol | 10 +++++----- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/contracts/AbstractARM.sol b/src/contracts/AbstractARM.sol index 90987d4..d6ca721 100644 --- a/src/contracts/AbstractARM.sol +++ b/src/contracts/AbstractARM.sol @@ -12,9 +12,9 @@ abstract contract AbstractARM is OwnableOperable, ERC20Upgradeable { /// Constants //////////////////////////////////////////////////// - /// @notice Maximum amount the Operator can set the price from 1 scaled to 36 decimals. - /// 2e33 is a 0.02% deviation, or 2 basis points. - uint256 public constant MAX_PRICE_DEVIATION = 2e32; + /// @notice Maximum amount the Owner can set the cross price below 1 scaled to 36 decimals. + /// 20e32 is a 0.2% deviation, or 20 basis points. + uint256 public constant MAX_CROSS_PRICE_DEVIATION = 20e32; /// @notice Scale of the prices. uint256 public constant PRICE_SCALE = 1e36; /// @dev The amount of shares that are minted to a dead address on initalization @@ -391,8 +391,17 @@ abstract contract AbstractARM is OwnableOperable, ERC20Upgradeable { emit TraderateChanged(_baseToTokenRate, _tokenToBaseRate); } + /** + * @notice set the price that buy and sell prices can not cross. + * That is, the buy prices must be below the cross price + * and the sell prices must be above the cross price. + * If the cross price is being lowered, there can not be any base assets in the ARM. eg stETH. + * The base assets should be sent to the withdrawal queue before the cross price can be lowered. + * The cross price can be increased with assets in the ARM. + * @param newCrossPrice The new cross price scaled to 36 decimals. + */ function setCrossPrice(uint256 newCrossPrice) external onlyOwner { - require(newCrossPrice >= PRICE_SCALE - MAX_PRICE_DEVIATION, "ARM: cross price too low"); + require(newCrossPrice >= PRICE_SCALE - MAX_CROSS_PRICE_DEVIATION, "ARM: cross price too low"); require(newCrossPrice <= PRICE_SCALE, "ARM: cross price too high"); // If the new cross price is lower than the current cross price diff --git a/test/fork/LidoFixedPriceMultiLpARM/Setters.t.sol b/test/fork/LidoFixedPriceMultiLpARM/Setters.t.sol index 55e3456..20964a3 100644 --- a/test/fork/LidoFixedPriceMultiLpARM/Setters.t.sol +++ b/test/fork/LidoFixedPriceMultiLpARM/Setters.t.sol @@ -173,9 +173,9 @@ contract Fork_Concrete_lidoARM_Setters_Test_ is Fork_Shared_Test_ { } function test_RevertWhen_SetCrossPrice_Because_PriceRange() public asLidoARMOwner { - // 3 basis points lower than 1.0 + // 21 basis points lower than 1.0 vm.expectRevert("ARM: cross price too low"); - lidoARM.setCrossPrice(0.9997e36); + lidoARM.setCrossPrice(0.9979e36); // 1 basis points higher than 1.0 vm.expectRevert("ARM: cross price too high"); @@ -201,10 +201,10 @@ contract Fork_Concrete_lidoARM_Setters_Test_ is Fork_Shared_Test_ { emit AbstractARM.CrossPriceUpdated(1e36); lidoARM.setCrossPrice(1e36); - // 2 basis points lower than 1.0 + // 20 basis points lower than 1.0 vm.expectEmit({emitter: address(lidoARM)}); - emit AbstractARM.CrossPriceUpdated(0.9998e36); - lidoARM.setCrossPrice(0.9998e36); + emit AbstractARM.CrossPriceUpdated(0.9980e36); + lidoARM.setCrossPrice(0.9980e36); } function test_SetCrossPrice_With_StETH_PriceUp_Owner() public {