Skip to content

Commit

Permalink
tests(ssr): add SSR to SystemValues checks
Browse files Browse the repository at this point in the history
  • Loading branch information
amusingaxl committed Sep 10, 2024
1 parent 560e1b3 commit 6870eb9
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 17 deletions.
60 changes: 43 additions & 17 deletions src/DssSpell.t.base.sol
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ interface FlapOracleLike {
// TODO: add full interfaces to dss-interfaces and remove from here
interface UsdsJoinLike is DaiJoinAbstract {}

interface SUsdsLike is GemAbstract {
function ssr() external view returns (uint256);
}

interface LitePsmLike {
function bud(address) external view returns (uint256);
function buf() external view returns (uint256);
Expand Down Expand Up @@ -226,6 +230,7 @@ contract DssSpellTestBase is Config, DssTest {
DaiAbstract dai = DaiAbstract( addr.addr("MCD_DAI"));
DaiJoinAbstract daiJoin = DaiJoinAbstract( addr.addr("MCD_JOIN_DAI"));
GemAbstract usds = GemAbstract( addr.addr("USDS"));
SUsdsLike susds = SUsdsLike( addr.addr("SUSDS"));
UsdsJoinLike usdsJoin = UsdsJoinLike( addr.addr("USDS_JOIN"));
DSTokenAbstract gov = DSTokenAbstract( addr.addr("MCD_GOV"));
GemAbstract sky = GemAbstract( addr.addr("SKY"));
Expand Down Expand Up @@ -476,6 +481,23 @@ contract DssSpellTestBase is Config, DssTest {
"TestError/pot-dsr-rates-table"
);

// ssr
uint256 expectedSSRRate = rates.rates(values.susds_ssr);
// make sure dsr is less than 100% APR
// bc -l <<< 'scale=27; e( l(2.00)/(60 * 60 * 24 * 365) )'
// 1000000021979553151239153027
assertEq(susds.ssr(), expectedSSRRate, "TestError/susds-ssr-expected-value");
assertTrue(
susds.ssr() >= RAY && susds.ssr() < 1000000021979553151239153027,
"TestError/susds-ssr-range"
);
assertTrue(
_diffCalc(_expectedRate(values.susds_ssr), _yearlyYield(expectedSSRRate)) <= TOLERANCE,
"TestError/susds-ssr-rates-table"
);
// SSR should always be higher than or equal to DSR
assertGe(expectedSSRRate, expectedDSRRate, "TestError/ssr-lower-than-dsr");

{
// Line values in RAD
assertTrue(
Expand Down Expand Up @@ -2504,11 +2526,11 @@ contract DssSpellTestBase is Config, DssTest {
_scheduleWaitAndCast(address(spell));
assertTrue(spell.done());

assertEq(vow.flapper(), address(split), "testSplitter/invalid-vow-flapper");
assertEq(split.flapper(), address(flap), "testSplitter/invalid-split-flapper");
assertEq(flap.gem(), address(sky), "testSplitter/invalid-flapper-gem");
assertEq(flap.pip(), addr.addr("FLAP_SKY_ORACLE"), "testSplitter/invalid-flapper-pip");
assertEq(flap.pair(), addr.addr("UNIV2USDSSKY"), "testSplitter/invalid-flapper-pair");
assertEq(vow.flapper(), address(split), "TestError/invalid-vow-flapper");
assertEq(split.flapper(), address(flap), "TestError/invalid-split-flapper");
assertEq(flap.gem(), address(sky), "TestError/invalid-flapper-gem");
assertEq(flap.pip(), addr.addr("FLAP_SKY_ORACLE"), "TestError/invalid-flapper-pip");
assertEq(flap.pair(), addr.addr("UNIV2USDSSKY"), "TestError/invalid-flapper-pair");

// Check splitter and flapper
{
Expand Down Expand Up @@ -2546,21 +2568,21 @@ contract DssSpellTestBase is Config, DssTest {
// Checking the farm balance is only relevant if split.burn() < 100%
if (split.burn() < 1 * WAD) {
pbalanceUsdsFarm = usds.balanceOf(split.farm());
assertFalse(split.farm() == address(0), "testSpliter/Splitter/missing-farm");
assertFalse(split.farm() == address(0), "TestError/Splitter/missing-farm");
}

vow.flap();

assertGt(pair.balanceOf(pauseProxy), pbalancePauseProxy, "testSplitter/Flapper/pair-pauseProxy-balance-no-increase");
assertGt(usds.balanceOf(address(pair)), preserveUsds, "testSplitter/Flapper/usds-pair-balance-no-increase");
assertEq(sky.balanceOf(address(pair)), preserveSky, "testSplitter/Flapper/unexpected-sky-pair-balance-change");
assertGt(pdaiVow - vat.dai(address(vow)), vow.bump() * 9 / 10, "testSplitter/Flapper/vat-dai-vow-change-too-low");
assertLt(pdaiVow - vat.dai(address(vow)), vow.bump() * 11 / 10, "testSplitter/Flapper/vat-dai-vow-change-too-high");
assertEq(usds.balanceOf(address(flap)), 0, "testSplitter/Flapper/invalid-usds-balance");
assertEq(sky.balanceOf(address(flap)), 0, "testSplitter/Flapper/invalid-sky-balance");
assertGt(pair.balanceOf(pauseProxy), pbalancePauseProxy, "TestError/Flapper/pair-pauseProxy-balance-no-increase");
assertGt(usds.balanceOf(address(pair)), preserveUsds, "TestError/Flapper/usds-pair-balance-no-increase");
assertEq(sky.balanceOf(address(pair)), preserveSky, "TestError/Flapper/unexpected-sky-pair-balance-change");
assertGt(pdaiVow - vat.dai(address(vow)), vow.bump() * 9 / 10, "TestError/Flapper/vat-dai-vow-change-too-low");
assertLt(pdaiVow - vat.dai(address(vow)), vow.bump() * 11 / 10, "TestError/Flapper/vat-dai-vow-change-too-high");
assertEq(usds.balanceOf(address(flap)), 0, "TestError/Flapper/invalid-usds-balance");
assertEq(sky.balanceOf(address(flap)), 0, "TestError/Flapper/invalid-sky-balance");

if (split.burn() < 1 * WAD) {
assertEq(usds.balanceOf(split.farm()), pbalanceUsdsFarm + payWad, "testSplitter/Splitter/invalid-farm-balance");
assertEq(usds.balanceOf(split.farm()), pbalanceUsdsFarm + payWad, "TestError/Splitter/invalid-farm-balance");
}
}

Expand All @@ -2580,13 +2602,17 @@ contract DssSpellTestBase is Config, DssTest {
assertTrue(spell.done());

// USDS is upgradeable, so we need to ensure the implementation contract address is correct.
assertEq(_imp(addr.addr("USDS")), addr.addr("USDS_IMP"), "testSystemTokens/invalid-usds-implementation");
assertEq(_imp(address(usds)), addr.addr("USDS_IMP"), "TestError/invalid-usds-implementation");

// sUSDS is upgradeable, so we need to ensure the implementation contract address is correct.
assertEq(_imp(addr.addr("SUSDS")), addr.addr("SUSDS_IMP"), "testSystemTokens/invalid-susds-implementation");
assertEq(_imp(address(susds)), addr.addr("SUSDS_IMP"), "TestError/invalid-susds-implementation");

// Checks that MCD_VEST_SKY is ward of SKY
assertEq(WardsAbstract(address(sky)).wards(addr.addr("MCD_VEST_SKY")), 1, "TestError/sky-vest-cannot-mint-sky");

// Checks that SUSDS is ward of MCD_VAT, otherwise it cannot call `vat.suck()`
// Checks that MCD_VEST_SKY is ward of SKY
assertEq(WardsAbstract(addr.addr("SKY")).wards(addr.addr("MCD_VEST_SKY")), 1, "testSytemTokens/sky-vest-cannot-mint-sky");
assertEq(vat.wards(address(susds)), 1, "TestError/susds-canot-suck-vat");
}

// Obtained as `bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)`
Expand Down
2 changes: 2 additions & 0 deletions src/test/config.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ contract Config {
struct SystemValues {
uint256 line_offset;
uint256 pot_dsr;
uint256 susds_ssr;
uint256 pause_delay;
uint256 vow_wait;
uint256 vow_dump;
Expand Down Expand Up @@ -114,6 +115,7 @@ contract Config {
//
afterSpell.line_offset = 680 * MILLION; // Offset between the global line against the sum of local lines
afterSpell.pot_dsr = 6_00; // In basis points
afterSpell.susds_ssr = 6_25; // In basis points
afterSpell.pause_delay = 16 hours; // In seconds
afterSpell.vow_wait = 156 hours; // In seconds
afterSpell.vow_dump = 250; // In whole Dai units
Expand Down

0 comments on commit 6870eb9

Please sign in to comment.