Commit 4490fa8e authored by Maurelian's avatar Maurelian Committed by GitHub

feat: Scaffolding for DeployAuthSystem Script (#11908)

* feat: Scaffolding for DeployAuthSystem Script

* feat: Remove redundant documentation

* Update DeployAuthSystem.s.sol
parent 3b4fcc5a
......@@ -76,3 +76,46 @@ contract DeployAuthSystemOutput is CommonBase {
return _safe;
}
}
contract DeployAuthSystem is Script {
function run(string memory _infile, string memory _outfile) public {
(DeployAuthSystemInput dasi, DeployAuthSystemOutput daso) = etchIOContracts();
dasi.loadInputFile(_infile);
run(dasi, daso);
daso.writeOutputFile(_outfile);
}
function run(DeployAuthSystemInput _dasi, DeployAuthSystemOutput _daso) public {
deploySafe(_dasi, _daso);
}
function deploySafe(DeployAuthSystemInput _dasi, DeployAuthSystemOutput _daso) public {
address[] memory owners = _dasi.owners();
uint256 threshold = _dasi.threshold();
// TODO: replace with a real deployment. The safe deployment logic is fairly complex, so for the purposes of
// this scaffolding PR we'll just etch the code.
address safe = makeAddr("safe");
vm.etch(safe, type(Safe).runtimeCode);
vm.store(safe, bytes32(uint256(3)), bytes32(uint256(owners.length)));
vm.store(safe, bytes32(uint256(4)), bytes32(uint256(threshold)));
_daso.set(_daso.safe.selector, safe);
}
function etchIOContracts() public returns (DeployAuthSystemInput dasi_, DeployAuthSystemOutput daso_) {
(dasi_, daso_) = getIOContracts();
vm.etch(address(dasi_), type(DeployAuthSystemInput).runtimeCode);
vm.etch(address(daso_), type(DeployAuthSystemOutput).runtimeCode);
vm.allowCheatcodes(address(dasi_));
vm.allowCheatcodes(address(daso_));
}
function getIOContracts() public view returns (DeployAuthSystemInput dasi_, DeployAuthSystemOutput daso_) {
dasi_ = DeployAuthSystemInput(DeployUtils.toIOAddress(msg.sender, "optimism.DeployAuthSystemInput"));
daso_ = DeployAuthSystemOutput(DeployUtils.toIOAddress(msg.sender, "optimism.DeployAuthSystemOutput"));
}
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol";
import { Test, stdStorage, StdStorage } from "forge-std/Test.sol";
import { stdToml } from "forge-std/StdToml.sol";
import { Solarray } from "scripts/libraries/Solarray.sol";
import { DeployAuthSystemInput, DeployAuthSystemOutput } from "scripts/DeployAuthSystem.s.sol";
import { DeployAuthSystemInput, DeployAuthSystem, DeployAuthSystemOutput } from "scripts/DeployAuthSystem.s.sol";
contract DeployAuthSystemInput_Test is Test {
DeployAuthSystemInput dasi;
......@@ -68,13 +68,10 @@ contract DeployAuthSystemOutput_Test is Test {
function test_set_succeeds() public {
address safeAddr = makeAddr("safe");
// Ensure the address has code, since it's expected to be a contract
vm.etch(safeAddr, hex"01");
// Set the output data
daso.set(daso.safe.selector, safeAddr);
// Compare the test data to the getter method
assertEq(safeAddr, address(daso.safe()), "100");
}
......@@ -95,13 +92,11 @@ contract DeployAuthSystemOutput_Test is Test {
function test_writeOutputFile_succeeds() public {
string memory root = vm.projectRoot();
// Use the expected data from the test fixture.
string memory expOutPath = string.concat(root, "/test/fixtures/test-deploy-auth-system-out.toml");
string memory expOutToml = vm.readFile(expOutPath);
address expSafe = expOutToml.readAddress(".safe");
// Etch code at each address so the code checks pass when settings values.
vm.etch(expSafe, hex"01");
daso.set(daso.safe.selector, expSafe);
......@@ -110,9 +105,100 @@ contract DeployAuthSystemOutput_Test is Test {
daso.writeOutputFile(actOutPath);
string memory actOutToml = vm.readFile(actOutPath);
// Clean up before asserting so that we don't leave any files behind.
vm.removeFile(actOutPath);
assertEq(expOutToml, actOutToml);
}
}
contract DeployAuthSystem_Test is Test {
using stdStorage for StdStorage;
DeployAuthSystem deployAuthSystem;
DeployAuthSystemInput dasi;
DeployAuthSystemOutput daso;
// Define default input variables for testing.
uint256 defaultThreshold = 5;
uint256 defaultOwnersLength = 7;
address[] defaultOwners;
function setUp() public {
deployAuthSystem = new DeployAuthSystem();
(dasi, daso) = deployAuthSystem.etchIOContracts();
for (uint256 i = 0; i < defaultOwnersLength; i++) {
defaultOwners.push(makeAddr(string.concat("owner", vm.toString(i))));
}
}
function hash(bytes32 _seed, uint256 _i) internal pure returns (bytes32) {
return keccak256(abi.encode(_seed, _i));
}
function testFuzz_run_memory_succeeds(bytes32 _seed) public {
address[] memory _owners = Solarray.addresses(
address(uint160(uint256(hash(_seed, 0)))),
address(uint160(uint256(hash(_seed, 1)))),
address(uint160(uint256(hash(_seed, 2)))),
address(uint160(uint256(hash(_seed, 3)))),
address(uint160(uint256(hash(_seed, 4)))),
address(uint160(uint256(hash(_seed, 5)))),
address(uint160(uint256(hash(_seed, 6))))
);
uint256 threshold = bound(uint256(_seed), 1, _owners.length - 1);
dasi.set(dasi.owners.selector, _owners);
dasi.set(dasi.threshold.selector, threshold);
deployAuthSystem.run(dasi, daso);
assertNotEq(address(daso.safe()), address(0), "100");
assertEq(daso.safe().getThreshold(), threshold, "200");
// TODO: the getOwners() method requires iterating over the owners linked list.
// Since we're not yet performing a proper deployment of the Safe, this call will revert.
// assertEq(daso.safe().getOwners().length, _owners.length, "300");
// Architecture assertions.
// TODO: these will become relevant as we add more contracts to the auth system, and need to test their
// relationships.
daso.checkOutput();
}
function test_run_io_succeeds() public {
string memory root = vm.projectRoot();
string memory inpath = string.concat(root, "/test/fixtures/test-deploy-auth-system-in.toml");
string memory outpath = string.concat(root, "/.testdata/test-deploy-auth-system-out.toml");
deployAuthSystem.run(inpath, outpath);
string memory actOutToml = vm.readFile(outpath);
string memory expOutToml = vm.readFile(string.concat(root, "/test/fixtures/test-deploy-auth-system-out.toml"));
vm.removeFile(outpath);
assertEq(expOutToml, actOutToml);
}
function test_run_NullInput_reverts() public {
dasi.set(dasi.owners.selector, defaultOwners);
dasi.set(dasi.threshold.selector, defaultThreshold);
// Zero out the owners length slot
uint256 slot = 9;
vm.store(address(dasi), bytes32(uint256(9)), bytes32(0));
vm.expectRevert("DeployAuthSystemInput: owners not set");
deployAuthSystem.run(dasi, daso);
vm.store(address(dasi), bytes32(uint256(9)), bytes32(defaultOwnersLength));
slot = zeroOutSlotForSelector(dasi.threshold.selector);
vm.expectRevert("DeployAuthSystemInput: threshold not set");
deployAuthSystem.run(dasi, daso);
vm.store(address(dasi), bytes32(slot), bytes32(defaultThreshold));
}
function zeroOutSlotForSelector(bytes4 _selector) internal returns (uint256 slot_) {
slot_ = stdstore.enable_packed_slots().target(address(dasi)).sig(_selector).find();
vm.store(address(dasi), bytes32(slot_), bytes32(0));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment