From 225260b5b6e86d08875beb74532a549bd80d5a3a Mon Sep 17 00:00:00 2001 From: Brian McMichael Date: Fri, 10 Feb 2023 20:12:41 -0500 Subject: [PATCH 1/5] Utilizes rollfork to obsolete deploy-info script --- src/DssSpell.t.base.sol | 62 ++++++++++++++++++++++++++++------------- src/test/config.sol | 4 --- 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/DssSpell.t.base.sol b/src/DssSpell.t.base.sol index a4827611..4e0c0736 100644 --- a/src/DssSpell.t.base.sol +++ b/src/DssSpell.t.base.sol @@ -266,22 +266,50 @@ contract DssSpellTestBase is Config, DssTest { function setUp() public { setValues(address(chief)); - spellValues.deployed_spell_created = spellValues.deployed_spell != address(0) ? spellValues.deployed_spell_created : block.timestamp; + if (spellValues.deployed_spell != address(0)) { + spell = DssSpell(spellValues.deployed_spell); + if (spell.eta() != 0) { + // if we have a scheduled spell in the config + // we want to roll our fork to the block where it was deployed + // this means the test suite will continue to accurately pass/fail + // even if mainnet has already scheduled/cast the spell + vm.makePersistent(address(this)); + vm.makePersistent(address(rates)); + vm.makePersistent(address(addr)); + vm.makePersistent(address(deployers)); + _rollToDeployedSpellBlock(address(spell)); + } + } else { + spell = new DssSpell(); + } + _castPreviousSpell(); - spell = spellValues.deployed_spell != address(0) ? - DssSpell(spellValues.deployed_spell) : new DssSpell(); - - if (spellValues.deployed_spell_block != 0 && spell.eta() != 0) { - // if we have a deployed spell in the config - // we want to roll our fork to the block where it was deployed - // this means the test suite will continue to accurately pass/fail - // even if mainnet has already scheduled/cast the spell - vm.makePersistent(address(this)); - vm.makePersistent(address(rates)); - vm.makePersistent(address(addr)); - vm.makePersistent(address(deployers)); - vm.rollFork(spellValues.deployed_spell_block); + } + + function _rollToDeployedSpellBlock(address _spell) internal { + if (_spell == address(0)) { vm.rollFork(block.number); } + + uint256 low = 5273074; // MCD_VAT Deployed Aug-06-2021 04:26:38 PM +UTC + uint256 high = block.number; + uint256 mid; + + while (low != high) { + mid = (low + high) / 2; + vm.rollFork(mid); + if (_isContractDeployed(_spell)) { + high = mid - 1; + } else { + low = mid + 1; + } } + + return vm.rollFork(low + 1); + } + + function _isContractDeployed(address _spell) internal view returns (bool) { + uint256 size; + assembly { size := extcodesize(_spell) } + return size > 0; } function _vote(address spell_) internal { @@ -1446,11 +1474,7 @@ contract DssSpellTestBase is Config, DssTest { assertEq(_stringToBytes32(spell.description()), _stringToBytes32(description), "TestError/spell-description"); - if(address(spell) != address(spellValues.deployed_spell)) { - assertEq(spell.expiration(), block.timestamp + spellValues.expiration_threshold, "TestError/spell-expiration"); - } else { - assertEq(spell.expiration(), spellValues.deployed_spell_created + spellValues.expiration_threshold, "TestError/spell-expiration"); - } + assertEq(spell.expiration(), block.timestamp + spellValues.expiration_threshold, "TestError/spell-expiration"); assertTrue(spell.officeHours() == spellValues.office_hours_enabled, "TestError/spell-office-hours"); diff --git a/src/test/config.sol b/src/test/config.sol index bb59222a..47eb1ad7 100644 --- a/src/test/config.sol +++ b/src/test/config.sol @@ -20,8 +20,6 @@ contract Config { struct SpellValues { address deployed_spell; - uint256 deployed_spell_created; - uint256 deployed_spell_block; address previous_spell; bool office_hours_enabled; uint256 expiration_threshold; @@ -96,8 +94,6 @@ contract Config { // spellValues = SpellValues({ deployed_spell: address(0x89625bb73bA7Dccde985F690CEa2659525AB5b15), // populate with deployed spell if deployed - deployed_spell_created: 1675789032, // use `./scripts/get-created-timestamp.sh ` - deployed_spell_block: 8451434, // populate with the block where the spell was deployed previous_spell: address(0), // supply if there is a need to test prior to its cast() function being called on-chain. office_hours_enabled: false, // true if officehours is expected to be enabled in the spell expiration_threshold: 30 days // Amount of time before spell expires From 778a72d36420e2bb083827c092cf44b14b4e45d8 Mon Sep 17 00:00:00 2001 From: Brian McMichael Date: Fri, 10 Feb 2023 22:55:31 -0500 Subject: [PATCH 2/5] no return --- 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 4e0c0736..dfb233ca 100644 --- a/src/DssSpell.t.base.sol +++ b/src/DssSpell.t.base.sol @@ -303,7 +303,7 @@ contract DssSpellTestBase is Config, DssTest { } } - return vm.rollFork(low + 1); + vm.rollFork(low + 1); } function _isContractDeployed(address _spell) internal view returns (bool) { From 82d733ccbe7579b6fa90d3092e858b6399447112 Mon Sep 17 00:00:00 2001 From: Brian McMichael Date: Fri, 10 Feb 2023 22:57:18 -0500 Subject: [PATCH 3/5] return on 0 address --- src/DssSpell.t.base.sol | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/DssSpell.t.base.sol b/src/DssSpell.t.base.sol index dfb233ca..6ab47970 100644 --- a/src/DssSpell.t.base.sol +++ b/src/DssSpell.t.base.sol @@ -287,7 +287,10 @@ contract DssSpellTestBase is Config, DssTest { } function _rollToDeployedSpellBlock(address _spell) internal { - if (_spell == address(0)) { vm.rollFork(block.number); } + if (_spell == address(0)) { + vm.rollFork(block.number); + return; + } uint256 low = 5273074; // MCD_VAT Deployed Aug-06-2021 04:26:38 PM +UTC uint256 high = block.number; From 2d96dfe73eb68d12003f2aa233b57a0395480336 Mon Sep 17 00:00:00 2001 From: Nazzareno Date: Mon, 13 Feb 2023 15:16:39 +0000 Subject: [PATCH 4/5] Fix binary search (#167) --- 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 6ab47970..2b7d716b 100644 --- a/src/DssSpell.t.base.sol +++ b/src/DssSpell.t.base.sol @@ -296,17 +296,17 @@ contract DssSpellTestBase is Config, DssTest { uint256 high = block.number; uint256 mid; - while (low != high) { - mid = (low + high) / 2; + while (low < high) { + mid = (low & high) + (low ^ high) / 2; // rounds down vm.rollFork(mid); if (_isContractDeployed(_spell)) { - high = mid - 1; + high = mid; } else { low = mid + 1; } } - vm.rollFork(low + 1); + vm.rollFork(low); } function _isContractDeployed(address _spell) internal view returns (bool) { From 11cc64f8a4e1ee2cbbc6e1c0bcc0ee19f09d4e78 Mon Sep 17 00:00:00 2001 From: Chris Smith <1408372+iamchrissmith@users.noreply.github.com> Date: Mon, 20 Feb 2023 17:28:37 -0700 Subject: [PATCH 5/5] Infoless deploy test caching (#168) * add block start point caching * check low block first * don't write or roll a second time if low is correct' * move file var to function * forgot memory --- foundry.toml | 3 ++- spellblock.txt | 1 + src/DssSpell.t.base.sol | 25 +++++++++++++++---------- 3 files changed, 18 insertions(+), 11 deletions(-) create mode 100644 spellblock.txt diff --git a/foundry.toml b/foundry.toml index f2c73111..b261c819 100644 --- a/foundry.toml +++ b/foundry.toml @@ -4,7 +4,8 @@ out = 'out' libs = ['lib'] fs_permissions = [ { access = "read", path = "./lib/dss-test/script/input/"}, - { access = "read", path = "./out/ArbitrumDomain.sol/ArbSysOverride.json"} + { access = "read", path = "./out/ArbitrumDomain.sol/ArbSysOverride.json"}, + { access = "read-write", path = "./spellblock.txt"} ] [rpc_endpoints] diff --git a/spellblock.txt b/spellblock.txt new file mode 100644 index 00000000..18a042d9 --- /dev/null +++ b/spellblock.txt @@ -0,0 +1 @@ +8451434 \ No newline at end of file diff --git a/src/DssSpell.t.base.sol b/src/DssSpell.t.base.sol index 2b7d716b..f01ac45c 100644 --- a/src/DssSpell.t.base.sol +++ b/src/DssSpell.t.base.sol @@ -292,21 +292,26 @@ contract DssSpellTestBase is Config, DssTest { return; } - uint256 low = 5273074; // MCD_VAT Deployed Aug-06-2021 04:26:38 PM +UTC + string memory spellBlockPath = "./spellblock.txt"; + + uint256 low = vm.parseUint(vm.readLine(spellBlockPath)); uint256 high = block.number; uint256 mid; - while (low < high) { - mid = (low & high) + (low ^ high) / 2; // rounds down - vm.rollFork(mid); - if (_isContractDeployed(_spell)) { - high = mid; - } else { - low = mid + 1; + vm.rollFork(low); + if (!_isContractDeployed(_spell)) { + while (low < high) { + mid = (low & high) + (low ^ high) / 2; // rounds down + vm.rollFork(mid); + if (_isContractDeployed(_spell)) { + high = mid; + } else { + low = mid + 1; + } } + vm.writeFile(spellBlockPath, vm.toString(low)); + vm.rollFork(low); } - - vm.rollFork(low); } function _isContractDeployed(address _spell) internal view returns (bool) {