From 16b4a1589a77cfe0b8c9ebca0aed4f39be480991 Mon Sep 17 00:00:00 2001 From: SidestreamStrongStrawberry Date: Thu, 28 Nov 2024 08:16:45 +0100 Subject: [PATCH 1/9] add test --- src/DssSpell.t.base.sol | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/DssSpell.t.base.sol b/src/DssSpell.t.base.sol index d2b480e4..08a92d48 100644 --- a/src/DssSpell.t.base.sol +++ b/src/DssSpell.t.base.sol @@ -961,6 +961,16 @@ contract DssSpellTestBase is Config, DssTest { address engine = LockstakeClipperLike(address(clip)).engine(); assertNotEq(engine, address(0), _concat("TestError/clip-engine-is-not-set-", ilk)); } + + if(values.collaterals[ilk].chop != 0 && values.collaterals[ilk].liqOn) { + // incentive is always smaller than liquidation penalty + (, uint256 chop,,) = dog.ilks(ilk); + (,,,, uint256 dust) = vat.ilks(ilk); + uint256 minimumDebt = dust == 0 ? RAD : dust; + uint256 penaltyAmount = (minimumDebt * chop / WAD) - minimumDebt; + uint256 incentiveAmount = uint256(clip.tip()) + (minimumDebt * uint256(clip.chip())) / WAD; + assertTrue(penaltyAmount >= incentiveAmount, _concat("TestError/too-low-dog-chop-", ilk)); + } } if (reg.class(ilk) < 3) { { From ad6df1d77e5c8186ae9998c66ddcc6aa676ebcfa Mon Sep 17 00:00:00 2001 From: SidestreamStrongStrawberry Date: Thu, 28 Nov 2024 12:06:19 +0100 Subject: [PATCH 2/9] chore: remove minimum debt value --- src/DssSpell.t.base.sol | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/DssSpell.t.base.sol b/src/DssSpell.t.base.sol index 08a92d48..d91bbc1e 100644 --- a/src/DssSpell.t.base.sol +++ b/src/DssSpell.t.base.sol @@ -966,9 +966,8 @@ contract DssSpellTestBase is Config, DssTest { // incentive is always smaller than liquidation penalty (, uint256 chop,,) = dog.ilks(ilk); (,,,, uint256 dust) = vat.ilks(ilk); - uint256 minimumDebt = dust == 0 ? RAD : dust; - uint256 penaltyAmount = (minimumDebt * chop / WAD) - minimumDebt; - uint256 incentiveAmount = uint256(clip.tip()) + (minimumDebt * uint256(clip.chip())) / WAD; + uint256 penaltyAmount = (dust * chop / WAD) - dust; + uint256 incentiveAmount = uint256(clip.tip()) + (dust * uint256(clip.chip())) / WAD; assertTrue(penaltyAmount >= incentiveAmount, _concat("TestError/too-low-dog-chop-", ilk)); } } From 529be9d33ce4e4eb4ea09df160f700e005435f15 Mon Sep 17 00:00:00 2001 From: SidestreamStrongStrawberry Date: Thu, 5 Dec 2024 10:33:22 +0100 Subject: [PATCH 3/9] chore: check line --- src/DssSpell.t.base.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DssSpell.t.base.sol b/src/DssSpell.t.base.sol index d91bbc1e..f51780b1 100644 --- a/src/DssSpell.t.base.sol +++ b/src/DssSpell.t.base.sol @@ -962,7 +962,7 @@ contract DssSpellTestBase is Config, DssTest { assertNotEq(engine, address(0), _concat("TestError/clip-engine-is-not-set-", ilk)); } - if(values.collaterals[ilk].chop != 0 && values.collaterals[ilk].liqOn) { + if(values.collaterals[ilk].line != 0 && values.collaterals[ilk].liqOn) { // incentive is always smaller than liquidation penalty (, uint256 chop,,) = dog.ilks(ilk); (,,,, uint256 dust) = vat.ilks(ilk); From 308cfe30c7d5642f135eb8c88a1eeff5e38c6673 Mon Sep 17 00:00:00 2001 From: SidestreamStrongStrawberry Date: Thu, 5 Dec 2024 10:51:28 +0100 Subject: [PATCH 4/9] chore: remove config --- src/DssSpell.t.base.sol | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/DssSpell.t.base.sol b/src/DssSpell.t.base.sol index f51780b1..0ae38420 100644 --- a/src/DssSpell.t.base.sol +++ b/src/DssSpell.t.base.sol @@ -962,10 +962,11 @@ contract DssSpellTestBase is Config, DssTest { assertNotEq(engine, address(0), _concat("TestError/clip-engine-is-not-set-", ilk)); } - if(values.collaterals[ilk].line != 0 && values.collaterals[ilk].liqOn) { + (,,,uint256 line,uint256 dust) = vat.ilks(ilk); + + if(line != 0 && clip.stopped() == 0) { // incentive is always smaller than liquidation penalty - (, uint256 chop,,) = dog.ilks(ilk); - (,,,, uint256 dust) = vat.ilks(ilk); + (,uint256 chop,,) = dog.ilks(ilk); uint256 penaltyAmount = (dust * chop / WAD) - dust; uint256 incentiveAmount = uint256(clip.tip()) + (dust * uint256(clip.chip())) / WAD; assertTrue(penaltyAmount >= incentiveAmount, _concat("TestError/too-low-dog-chop-", ilk)); From 52021bbbe93a5112467dbc80839cea44b338d82c Mon Sep 17 00:00:00 2001 From: SidestreamStrongStrawberry Date: Thu, 5 Dec 2024 10:53:45 +0100 Subject: [PATCH 5/9] chore: separate check --- src/DssSpell.t.base.sol | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/DssSpell.t.base.sol b/src/DssSpell.t.base.sol index 0ae38420..ef905149 100644 --- a/src/DssSpell.t.base.sol +++ b/src/DssSpell.t.base.sol @@ -961,15 +961,15 @@ contract DssSpellTestBase is Config, DssTest { address engine = LockstakeClipperLike(address(clip)).engine(); assertNotEq(engine, address(0), _concat("TestError/clip-engine-is-not-set-", ilk)); } - - (,,,uint256 line,uint256 dust) = vat.ilks(ilk); - - if(line != 0 && clip.stopped() == 0) { - // incentive is always smaller than liquidation penalty - (,uint256 chop,,) = dog.ilks(ilk); - uint256 penaltyAmount = (dust * chop / WAD) - dust; - uint256 incentiveAmount = uint256(clip.tip()) + (dust * uint256(clip.chip())) / WAD; - assertTrue(penaltyAmount >= incentiveAmount, _concat("TestError/too-low-dog-chop-", ilk)); + { + (,,,uint256 line,uint256 dust) = vat.ilks(ilk); + if(line != 0 && clip.stopped() == 0) { + // incentive is always smaller than liquidation penalty + (,uint256 chop,,) = dog.ilks(ilk); + uint256 penaltyAmount = (dust * chop / WAD) - dust; + uint256 incentiveAmount = uint256(clip.tip()) + (dust * uint256(clip.chip())) / WAD; + assertTrue(penaltyAmount >= incentiveAmount, _concat("TestError/too-low-dog-chop-", ilk)); + } } } if (reg.class(ilk) < 3) { From 372e226a47d94d45dc98a02b62015c29e1e1d82a Mon Sep 17 00:00:00 2001 From: SidestreamStrongStrawberry Date: Thu, 5 Dec 2024 11:50:31 +0100 Subject: [PATCH 6/9] chore: format --- src/DssSpell.t.base.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/DssSpell.t.base.sol b/src/DssSpell.t.base.sol index ef905149..133e4a7b 100644 --- a/src/DssSpell.t.base.sol +++ b/src/DssSpell.t.base.sol @@ -962,10 +962,10 @@ contract DssSpellTestBase is Config, DssTest { assertNotEq(engine, address(0), _concat("TestError/clip-engine-is-not-set-", ilk)); } { - (,,,uint256 line,uint256 dust) = vat.ilks(ilk); - if(line != 0 && clip.stopped() == 0) { - // incentive is always smaller than liquidation penalty - (,uint256 chop,,) = dog.ilks(ilk); + // Ensure liquidation penalty is always bigger than combined keeper incentives + (,,, uint256 line, uint256 dust) = vat.ilks(ilk); + if (line != 0 && clip.stopped() == 0) { + (, uint256 chop,,) = dog.ilks(ilk); uint256 penaltyAmount = (dust * chop / WAD) - dust; uint256 incentiveAmount = uint256(clip.tip()) + (dust * uint256(clip.chip())) / WAD; assertTrue(penaltyAmount >= incentiveAmount, _concat("TestError/too-low-dog-chop-", ilk)); From ef4348b01b835e4c707d5d551d5772140a7d21e9 Mon Sep 17 00:00:00 2001 From: SidestreamStrongStrawberry Date: Thu, 5 Dec 2024 14:53:23 +0100 Subject: [PATCH 7/9] feat: add vow.wait check --- src/DssSpell.t.base.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/DssSpell.t.base.sol b/src/DssSpell.t.base.sol index 133e4a7b..25e2edb1 100644 --- a/src/DssSpell.t.base.sol +++ b/src/DssSpell.t.base.sol @@ -685,6 +685,10 @@ contract DssSpellTestBase is Config, DssTest { // wait assertEq(vow.wait(), values.vow_wait, "TestError/vow-wait"); + + // This is a safety check to ensure that DAI holders have enough time to redeem their DAI from LPs + assertGe(vow.wait(), pause.delay() * 2, "TestError/vow-wait-too-short"); + { // dump values in WAD uint256 normalizedDump = values.vow_dump * WAD; From 04a182208685a3207412ae418f6fec764f22b4a1 Mon Sep 17 00:00:00 2001 From: SidestreamStrongStrawberry Date: Thu, 5 Dec 2024 15:28:19 +0100 Subject: [PATCH 8/9] chore: update comment --- src/DssSpell.t.base.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DssSpell.t.base.sol b/src/DssSpell.t.base.sol index 25e2edb1..3e103d70 100644 --- a/src/DssSpell.t.base.sol +++ b/src/DssSpell.t.base.sol @@ -686,7 +686,7 @@ contract DssSpellTestBase is Config, DssTest { // wait assertEq(vow.wait(), values.vow_wait, "TestError/vow-wait"); - // This is a safety check to ensure that DAI holders have enough time to redeem their DAI from LPs + // Ensure there is enough time for the governance to unwind SBE LP tokens instead of starting a Flop auction assertGe(vow.wait(), pause.delay() * 2, "TestError/vow-wait-too-short"); { From 3c19e6e831aa4e2e54964e8a512ea3f50e22b3c7 Mon Sep 17 00:00:00 2001 From: SidestreamStrongStrawberry Date: Wed, 11 Dec 2024 13:41:20 +0100 Subject: [PATCH 9/9] update incentive amount --- src/DssSpell.t.base.sol | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/DssSpell.t.base.sol b/src/DssSpell.t.base.sol index 898e2978..bfeabdf7 100644 --- a/src/DssSpell.t.base.sol +++ b/src/DssSpell.t.base.sol @@ -970,9 +970,10 @@ contract DssSpellTestBase is Config, DssTest { (,,, uint256 line, uint256 dust) = vat.ilks(ilk); if (line != 0 && clip.stopped() == 0) { (, uint256 chop,,) = dog.ilks(ilk); - uint256 penaltyAmount = (dust * chop / WAD) - dust; - uint256 incentiveAmount = uint256(clip.tip()) + (dust * uint256(clip.chip())) / WAD; - assertTrue(penaltyAmount >= incentiveAmount, _concat("TestError/too-low-dog-chop-", ilk)); + uint256 tab = dust * chop / WAD; + uint256 penaltyAmount = tab - dust; + uint256 incentiveAmount = uint256(clip.tip()) + (tab * uint256(clip.chip()) / WAD); + assertGe(penaltyAmount, incentiveAmount, _concat("TestError/too-low-dog-chop-", ilk)); } } }