Skip to content

Instantly share code, notes, and snippets.

@MerlinEgalite
Last active May 26, 2023 06:24
Show Gist options
  • Save MerlinEgalite/1a2c44f3de11a337d67fe9821b006196 to your computer and use it in GitHub Desktop.
Save MerlinEgalite/1a2c44f3de11a337d67fe9821b006196 to your computer and use it in GitHub Desktop.
Tornado Cash Governance Hack
pragma solidity >=0.8.0;
import "forge-std/Test.sol";
import "forge-std/console2.sol";
contract ContractA {
function destroy() public {
selfdestruct(payable(0));
}
}
contract ContractB {
function foo() public pure returns (uint256) {
return 1;
}
}
contract Deployer {
function deployA() public returns(address deployedAddress) {
deployedAddress = address(new ContractA());
console2.log(deployedAddress);
}
function deployB() public returns(address deployedAddress) {
deployedAddress = address(new ContractB());
console2.log(deployedAddress);
}
function destroy() public {
selfdestruct(payable(0));
}
}
contract CreateSelfdestruct is Test {
Deployer deployerA;
ContractA a;
ContractB b;
function setUp() public {
// Adding salt uses CREATE2 to deploy the Deployer contract.
deployerA = new Deployer{salt: "lfg"}();
a = ContractA(deployerA.deployA());
// Move to setUp because else the selfdestruct does not take effect.
// https://github.com/foundry-rs/foundry/issues/1543
a.destroy();
deployerA.destroy();
}
function testCreateDestruct() public {
// Make sure there's no code deployed on theses addresses anymore.
assertFalse(isContract(address(a)));
assertFalse(isContract(address(deployerA)));
Deployer deployerB = new Deployer{salt: "lfg"}();
b = ContractB(deployerB.deployB());
assertEq(address(a), address(b));
}
function isContract(address addr) private returns (bool isContract){
uint32 size;
assembly {
size := extcodesize(addr)
}
return (size > 0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment