Skip to content

Commit

Permalink
feat: Add rate provider zero check to constructor (#35)
Browse files Browse the repository at this point in the history
* feat: add rate provider check

* fix: update to reduce diff

* feat: update to get invariant test setup to work with new constructor
  • Loading branch information
lucas-manuel authored Aug 26, 2024
1 parent 60e7a3d commit 94e48b2
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 7 deletions.
4 changes: 2 additions & 2 deletions deploy/PSM3Deploy.sol
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.13;

import { PSM3 } from "src/PSM3.sol";

import { IERC20 } from "erc20-helpers/interfaces/IERC20.sol";

import { PSM3 } from "src/PSM3.sol";

library PSM3Deploy {

function deploy(
Expand Down
5 changes: 5 additions & 0 deletions src/PSM3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ contract PSM3 is IPSM3 {

rateProvider = rateProvider_;

require(
IRateProviderLike(rateProvider_).getConversionRate() != 0,
"PSM3/rate-provider-returns-zero"
);

_asset0Precision = 10 ** IERC20(asset0_).decimals();
_asset1Precision = 10 ** IERC20(asset1_).decimals();
_asset2Precision = 10 ** IERC20(asset2_).decimals();
Expand Down
21 changes: 21 additions & 0 deletions test/invariant/Invariants.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity ^0.8.13;
import "forge-std/Test.sol";

import { DSRAuthOracle } from "lib/xchain-dsr-oracle/src/DSRAuthOracle.sol";
import { IDSROracle } from "lib/xchain-dsr-oracle/src/interfaces/IDSROracle.sol";

import { PSM3 } from "src/PSM3.sol";

Expand Down Expand Up @@ -542,6 +543,16 @@ contract PSMInvariants_TimeBasedRateSetting_NoTransfer is PSMInvariantTestBase {

DSRAuthOracle dsrOracle = new DSRAuthOracle();

// Workaround to initialize PSM with an oracle that does not return zero
// This gets overwritten by the handler
dsrOracle.grantRole(dsrOracle.DATA_PROVIDER_ROLE(), address(this));
dsrOracle.setPotData(IDSROracle.PotData({
dsr: uint96(1e27),
chi: uint120(1e27),
rho: uint40(block.timestamp)
}));
dsrOracle.revokeRole(dsrOracle.DATA_PROVIDER_ROLE(), address(this));

// Redeploy PSM with new rate provider
psm = new PSM3(address(dai), address(usdc), address(sDai), address(dsrOracle));

Expand Down Expand Up @@ -611,6 +622,16 @@ contract PSMInvariants_TimeBasedRateSetting_WithTransfers is PSMInvariantTestBas

DSRAuthOracle dsrOracle = new DSRAuthOracle();

// Workaround to initialize PSM with an oracle that does not return zero
// This gets overwritten by the handler
dsrOracle.grantRole(dsrOracle.DATA_PROVIDER_ROLE(), address(this));
dsrOracle.setPotData(IDSROracle.PotData({
dsr: uint96(1e27),
chi: uint120(1e27),
rho: uint40(block.timestamp)
}));
dsrOracle.revokeRole(dsrOracle.DATA_PROVIDER_ROLE(), address(this));

// Redeploy PSM with new rate provider
psm = new PSM3(address(dai), address(usdc), address(sDai), address(dsrOracle));

Expand Down
7 changes: 2 additions & 5 deletions test/invariant/handlers/TimeBasedRateHandler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,9 @@ contract TimeBasedRateHandler is HandlerBase, StdCheats {
// 1. Setup and bounds
dsr = _bound(newDsr, 1e27, TWENTY_PCT_APY_DSR);

// Update rho to be current, update chi based on current rate
uint256 rho = block.timestamp;

// If chi hasn't been set yet, set to 1e27, else recalculate it in the same way it would
// happen during a refresh at `rho`
uint256 rate = dsrOracle.getConversionRate(rho);
uint256 chi = rate == 0 ? 1e27 : rate;
uint256 chi = dsrOracle.getConversionRate(rho);

// 2. Cache starting state
uint256 startingConversion = psm.convertToAssetValue(1e18);
Expand Down
8 changes: 8 additions & 0 deletions test/unit/Constructor.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { PSM3 } from "src/PSM3.sol";

import { PSMTestBase } from "test/PSMTestBase.sol";

import { MockRateProvider } from "test/mocks/MockRateProvider.sol";

contract PSMConstructorTests is PSMTestBase {

function test_constructor_invalidAsset0() public {
Expand Down Expand Up @@ -44,6 +46,12 @@ contract PSMConstructorTests is PSMTestBase {
new PSM3(address(dai), address(usdc), address(usdc), address(rateProvider));
}

function test_constructor_rateProviderZero() public {
MockRateProvider(address(rateProvider)).__setConversionRate(0);
vm.expectRevert("PSM3/rate-provider-returns-zero");
new PSM3(address(dai), address(usdc), address(sDai), address(rateProvider));
}

function test_constructor() public {
// Deploy new PSM to get test coverage
psm = new PSM3(address(dai), address(usdc), address(sDai), address(rateProvider));
Expand Down

0 comments on commit 94e48b2

Please sign in to comment.