From effdda3657f71fd6efc3465dc661b375d1bacc3e Mon Sep 17 00:00:00 2001 From: Kurt Barry Date: Fri, 25 Oct 2019 12:53:26 -0700 Subject: [PATCH] harden system against interference from governance during global settlement (#83) This largely ensures that malicious governance cannot prevent the Global Settlement process from completing successfully by messing with system parameters or authorizations. A minimal approach was taken in an attempt to only add meaningful defenses. --- src/end.sol | 9 ++++++--- src/spot.sol | 10 ++++++++++ src/test/end.t.sol | 1 + src/vat.sol | 6 ++++-- src/vow.sol | 3 ++- 5 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/end.sol b/src/end.sol index 8eff2508..72e1a17c 100644 --- a/src/end.sol +++ b/src/end.sol @@ -57,7 +57,6 @@ contract PotLike { function cage() external; } contract VowLike { - function heal(uint256 rad) external; function cage() external; } contract Flippy { @@ -86,6 +85,7 @@ contract Spotty { } function par() external view returns (uint256); function ilks(bytes32) external view returns (Ilk memory); + function cage() external; } /* @@ -191,8 +191,8 @@ contract Spotty { contract End is DSNote { // --- Auth --- mapping (address => uint) public wards; - function rely(address guy) external note auth { wards[guy] = 1; } - function deny(address guy) external note auth { wards[guy] = 0; } + function rely(address guy) external note auth { require(live == 1); wards[guy] = 1; } + function deny(address guy) external note auth { require(live == 1); wards[guy] = 0; } modifier auth { require(wards[msg.sender] == 1); _; } // --- Data --- @@ -249,6 +249,7 @@ contract End is DSNote { // --- Administration --- function file(bytes32 what, address data) external note auth { + require(live == 1); if (what == "vat") vat = VatLike(data); else if (what == "cat") cat = CatLike(data); else if (what == "vow") vow = VowLike(data); @@ -257,6 +258,7 @@ contract End is DSNote { else revert(); } function file(bytes32 what, uint256 data) external note auth { + require(live == 1); if (what == "wait") wait = data; else revert(); } @@ -269,6 +271,7 @@ contract End is DSNote { vat.cage(); cat.cage(); vow.cage(); + spot.cage(); pot.cage(); } diff --git a/src/spot.sol b/src/spot.sol index 0371095c..eecb9228 100644 --- a/src/spot.sol +++ b/src/spot.sol @@ -43,6 +43,8 @@ contract Spotter is DSNote { VatLike public vat; uint256 public par; // ref per dai + uint256 public live; + // --- Events --- event Poke( bytes32 ilk, @@ -55,6 +57,7 @@ contract Spotter is DSNote { wards[msg.sender] = 1; vat = VatLike(vat_); par = ONE; + live = 1; } // --- Math --- @@ -69,14 +72,17 @@ contract Spotter is DSNote { // --- Administration --- function file(bytes32 ilk, bytes32 what, address pip_) external note auth { + require(live == 1); if (what == "pip") ilks[ilk].pip = PipLike(pip_); else revert(); } function file(bytes32 what, uint data) external note auth { + require(live == 1); if (what == "par") par = data; else revert(); } function file(bytes32 ilk, bytes32 what, uint data) external note auth { + require(live == 1); if (what == "mat") ilks[ilk].mat = data; else revert(); } @@ -88,4 +94,8 @@ contract Spotter is DSNote { vat.file(ilk, "spot", spot); emit Poke(ilk, val, spot); } + + function cage() external note auth { + live = 0; + } } diff --git a/src/test/end.t.sol b/src/test/end.t.sol index 1541641e..63e3a5b6 100644 --- a/src/test/end.t.sol +++ b/src/test/end.t.sol @@ -212,6 +212,7 @@ contract EndTest is DSTest { end.file("wait", 1 hours); vat.rely(address(end)); vow.rely(address(end)); + spot.rely(address(end)); pot.rely(address(end)); cat.rely(address(end)); flap.rely(address(vow)); diff --git a/src/vat.sol b/src/vat.sol index 5adf46e7..9c9f06d3 100644 --- a/src/vat.sol +++ b/src/vat.sol @@ -20,8 +20,8 @@ pragma solidity 0.5.11; contract Vat { // --- Auth --- mapping (address => uint) public wards; - function rely(address usr) external note auth { wards[usr] = 1; } - function deny(address usr) external note auth { wards[usr] = 0; } + function rely(address usr) external note auth { require(live == 1); wards[usr] = 1; } + function deny(address usr) external note auth { require(live == 1); wards[usr] = 0; } modifier auth { require(wards[msg.sender] == 1); _; } mapping(address => mapping (address => uint)) public can; @@ -121,10 +121,12 @@ contract Vat { ilks[ilk].rate = 10 ** 27; } function file(bytes32 what, uint data) external note auth { + require(live == 1); if (what == "Line") Line = data; else revert(); } function file(bytes32 ilk, bytes32 what, uint data) external note auth { + require(live == 1); if (what == "spot") ilks[ilk].spot = data; else if (what == "line") ilks[ilk].line = data; else if (what == "dust") ilks[ilk].dust = data; diff --git a/src/vow.sol b/src/vow.sol index b591b737..117e90e3 100644 --- a/src/vow.sol +++ b/src/vow.sol @@ -41,7 +41,7 @@ contract VatLike { contract Vow is DSNote { // --- Auth --- mapping (address => uint) public wards; - function rely(address usr) external note auth { wards[usr] = 1; } + function rely(address usr) external note auth { require(live == 1); wards[usr] = 1; } function deny(address usr) external note auth { wards[usr] = 0; } modifier auth { require(wards[msg.sender] == 1); _; } @@ -134,6 +134,7 @@ contract Vow is DSNote { } function cage() external note auth { + require(live == 1); live = 0; Sin = 0; Ash = 0;